Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

UserRevisionLine numberNew contents of line
XinZhangMS 0:f7f1f0d76dd6 1 // Copyright (c) Microsoft. All rights reserved.
XinZhangMS 0:f7f1f0d76dd6 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
XinZhangMS 0:f7f1f0d76dd6 3
XinZhangMS 0:f7f1f0d76dd6 4 #include <stdlib.h>
XinZhangMS 0:f7f1f0d76dd6 5 #include <ctype.h>
XinZhangMS 0:f7f1f0d76dd6 6 #include "azure_c_shared_utility/optimize_size.h"
XinZhangMS 0:f7f1f0d76dd6 7 #include "azure_c_shared_utility/gballoc.h"
XinZhangMS 0:f7f1f0d76dd6 8 #include "azure_c_shared_utility/crt_abstractions.h"
XinZhangMS 0:f7f1f0d76dd6 9 #include "azure_c_shared_utility/string_tokenizer.h"
XinZhangMS 0:f7f1f0d76dd6 10 #include "azure_c_shared_utility/singlylinkedlist.h"
XinZhangMS 0:f7f1f0d76dd6 11 #include "azure_c_shared_utility/buffer_.h"
XinZhangMS 0:f7f1f0d76dd6 12 #include "azure_c_shared_utility/xlogging.h"
XinZhangMS 0:f7f1f0d76dd6 13 #include "azure_c_shared_utility/httpapiex.h"
XinZhangMS 0:f7f1f0d76dd6 14 #include "azure_c_shared_utility/httpapiexsas.h"
XinZhangMS 0:f7f1f0d76dd6 15 #include "azure_c_shared_utility/base64.h"
XinZhangMS 0:f7f1f0d76dd6 16 #include "azure_c_shared_utility/uniqueid.h"
XinZhangMS 0:f7f1f0d76dd6 17 #include "azure_c_shared_utility/connection_string_parser.h"
XinZhangMS 0:f7f1f0d76dd6 18
XinZhangMS 0:f7f1f0d76dd6 19 #include "parson.h"
XinZhangMS 0:f7f1f0d76dd6 20 #include "iothub_devicetwin.h"
XinZhangMS 0:f7f1f0d76dd6 21 #include "iothub_sc_version.h"
XinZhangMS 0:f7f1f0d76dd6 22
XinZhangMS 0:f7f1f0d76dd6 23 #define IOTHUB_TWIN_REQUEST_MODE_VALUES \
XinZhangMS 0:f7f1f0d76dd6 24 IOTHUB_TWIN_REQUEST_GET, \
XinZhangMS 0:f7f1f0d76dd6 25 IOTHUB_TWIN_REQUEST_UPDATE, \
XinZhangMS 0:f7f1f0d76dd6 26 IOTHUB_TWIN_REQUEST_REPLACE_TAGS, \
XinZhangMS 0:f7f1f0d76dd6 27 IOTHUB_TWIN_REQUEST_REPLACE_DESIRED, \
XinZhangMS 0:f7f1f0d76dd6 28 IOTHUB_TWIN_REQUEST_UPDATE_DESIRED
XinZhangMS 0:f7f1f0d76dd6 29
XinZhangMS 0:f7f1f0d76dd6 30 DEFINE_ENUM(IOTHUB_TWIN_REQUEST_MODE, IOTHUB_TWIN_REQUEST_MODE_VALUES);
XinZhangMS 0:f7f1f0d76dd6 31 DEFINE_ENUM_STRINGS(IOTHUB_DEVICE_TWIN_RESULT, IOTHUB_DEVICE_TWIN_RESULT_VALUES);
XinZhangMS 0:f7f1f0d76dd6 32
XinZhangMS 0:f7f1f0d76dd6 33 #define HTTP_HEADER_KEY_AUTHORIZATION "Authorization"
XinZhangMS 0:f7f1f0d76dd6 34 #define HTTP_HEADER_VAL_AUTHORIZATION " "
XinZhangMS 0:f7f1f0d76dd6 35 #define HTTP_HEADER_KEY_REQUEST_ID "Request-Id"
XinZhangMS 0:f7f1f0d76dd6 36 #define HTTP_HEADER_KEY_USER_AGENT "User-Agent"
XinZhangMS 0:f7f1f0d76dd6 37 #define HTTP_HEADER_VAL_USER_AGENT IOTHUB_SERVICE_CLIENT_TYPE_PREFIX IOTHUB_SERVICE_CLIENT_BACKSLASH IOTHUB_SERVICE_CLIENT_VERSION
XinZhangMS 0:f7f1f0d76dd6 38 #define HTTP_HEADER_KEY_ACCEPT "Accept"
XinZhangMS 0:f7f1f0d76dd6 39 #define HTTP_HEADER_VAL_ACCEPT "application/json"
XinZhangMS 0:f7f1f0d76dd6 40 #define HTTP_HEADER_KEY_CONTENT_TYPE "Content-Type"
XinZhangMS 0:f7f1f0d76dd6 41 #define HTTP_HEADER_VAL_CONTENT_TYPE "application/json; charset=utf-8"
XinZhangMS 0:f7f1f0d76dd6 42 #define HTTP_HEADER_KEY_IFMATCH "If-Match"
XinZhangMS 0:f7f1f0d76dd6 43 #define HTTP_HEADER_VAL_IFMATCH "*"
XinZhangMS 0:f7f1f0d76dd6 44 #define UID_LENGTH 37
XinZhangMS 0:f7f1f0d76dd6 45
XinZhangMS 0:f7f1f0d76dd6 46 static const char* URL_API_VERSION = "?api-version=2017-11-08-preview";
XinZhangMS 0:f7f1f0d76dd6 47
XinZhangMS 0:f7f1f0d76dd6 48 static const char* RELATIVE_PATH_FMT_TWIN = "/twins/%s%s";
XinZhangMS 0:f7f1f0d76dd6 49 static const char* RELATIVE_PATH_FMT_TWIN_MODULE = "/twins/%s/modules/%s%s";
XinZhangMS 0:f7f1f0d76dd6 50
XinZhangMS 0:f7f1f0d76dd6 51
XinZhangMS 0:f7f1f0d76dd6 52 /** @brief Structure to store IoTHub authentication information
XinZhangMS 0:f7f1f0d76dd6 53 */
XinZhangMS 0:f7f1f0d76dd6 54 typedef struct IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_TAG
XinZhangMS 0:f7f1f0d76dd6 55 {
XinZhangMS 0:f7f1f0d76dd6 56 char* hostname;
XinZhangMS 0:f7f1f0d76dd6 57 char* sharedAccessKey;
XinZhangMS 0:f7f1f0d76dd6 58 char* keyName;
XinZhangMS 0:f7f1f0d76dd6 59 } IOTHUB_SERVICE_CLIENT_DEVICE_TWIN;
XinZhangMS 0:f7f1f0d76dd6 60
XinZhangMS 0:f7f1f0d76dd6 61 static const char* generateGuid(void)
XinZhangMS 0:f7f1f0d76dd6 62 {
XinZhangMS 0:f7f1f0d76dd6 63 char* result;
XinZhangMS 0:f7f1f0d76dd6 64
XinZhangMS 0:f7f1f0d76dd6 65 if ((result = malloc(UID_LENGTH)) != NULL)
XinZhangMS 0:f7f1f0d76dd6 66 {
XinZhangMS 0:f7f1f0d76dd6 67 result[0] = '\0';
XinZhangMS 0:f7f1f0d76dd6 68 if (UniqueId_Generate(result, UID_LENGTH) != UNIQUEID_OK)
XinZhangMS 0:f7f1f0d76dd6 69 {
XinZhangMS 0:f7f1f0d76dd6 70 free((void*)result);
XinZhangMS 0:f7f1f0d76dd6 71 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 72 }
XinZhangMS 0:f7f1f0d76dd6 73 }
XinZhangMS 0:f7f1f0d76dd6 74 return (const char*)result;
XinZhangMS 0:f7f1f0d76dd6 75 }
XinZhangMS 0:f7f1f0d76dd6 76
XinZhangMS 0:f7f1f0d76dd6 77 static STRING_HANDLE createRelativePath(IOTHUB_TWIN_REQUEST_MODE iotHubTwinRequestMode, const char* deviceId, const char* moduleId)
XinZhangMS 0:f7f1f0d76dd6 78 {
XinZhangMS 0:f7f1f0d76dd6 79 //IOTHUB_TWIN_REQUEST_GET GET {iot hub}/twins/{device id} // Get device twin
XinZhangMS 0:f7f1f0d76dd6 80 //IOTHUB_TWIN_REQUEST_UPDATE PATCH {iot hub}/twins/{device id} // Partally update device twin
XinZhangMS 0:f7f1f0d76dd6 81 //IOTHUB_TWIN_REQUEST_REPLACE_TAGS PUT {iot hub}/twins/{device id}/tags // Replace update tags
XinZhangMS 0:f7f1f0d76dd6 82 //IOTHUB_TWIN_REQUEST_REPLACE_DESIRED PUT {iot hub}/twins/{device id}/properties/desired // Replace update desired properties
XinZhangMS 0:f7f1f0d76dd6 83 //IOTHUB_TWIN_REQUEST_UPDATE_DESIRED PATCH {iot hub}/twins/{device id}/properties/desired // Partially update desired properties
XinZhangMS 0:f7f1f0d76dd6 84
XinZhangMS 0:f7f1f0d76dd6 85 STRING_HANDLE result;
XinZhangMS 0:f7f1f0d76dd6 86
XinZhangMS 0:f7f1f0d76dd6 87 if ((iotHubTwinRequestMode == IOTHUB_TWIN_REQUEST_GET) || (iotHubTwinRequestMode == IOTHUB_TWIN_REQUEST_UPDATE))
XinZhangMS 0:f7f1f0d76dd6 88 {
XinZhangMS 0:f7f1f0d76dd6 89 if (moduleId == NULL)
XinZhangMS 0:f7f1f0d76dd6 90 {
XinZhangMS 0:f7f1f0d76dd6 91 result = STRING_construct_sprintf(RELATIVE_PATH_FMT_TWIN, deviceId, URL_API_VERSION);
XinZhangMS 0:f7f1f0d76dd6 92 }
XinZhangMS 0:f7f1f0d76dd6 93 else
XinZhangMS 0:f7f1f0d76dd6 94 {
XinZhangMS 0:f7f1f0d76dd6 95 result = STRING_construct_sprintf(RELATIVE_PATH_FMT_TWIN_MODULE, deviceId, moduleId, URL_API_VERSION);
XinZhangMS 0:f7f1f0d76dd6 96 }
XinZhangMS 0:f7f1f0d76dd6 97 }
XinZhangMS 0:f7f1f0d76dd6 98 else
XinZhangMS 0:f7f1f0d76dd6 99 {
XinZhangMS 0:f7f1f0d76dd6 100 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 101 }
XinZhangMS 0:f7f1f0d76dd6 102 return result;
XinZhangMS 0:f7f1f0d76dd6 103 }
XinZhangMS 0:f7f1f0d76dd6 104
XinZhangMS 0:f7f1f0d76dd6 105 static HTTP_HEADERS_HANDLE createHttpHeader(IOTHUB_TWIN_REQUEST_MODE iotHubTwinRequestMode)
XinZhangMS 0:f7f1f0d76dd6 106 {
XinZhangMS 0:f7f1f0d76dd6 107 /*Codes_SRS_IOTHUBDEVICETWIN_12_020: [ IoTHubDeviceTwin_GetTwin shall add the following headers to the created HTTP GET request: authorization=sasToken,Request-Id=1001,Accept=application/json,Content-Type=application/json,charset=utf-8 ]*/
XinZhangMS 0:f7f1f0d76dd6 108 HTTP_HEADERS_HANDLE httpHeader;
XinZhangMS 0:f7f1f0d76dd6 109 const char* guid = NULL;
XinZhangMS 0:f7f1f0d76dd6 110
XinZhangMS 0:f7f1f0d76dd6 111 if ((httpHeader = HTTPHeaders_Alloc()) == NULL)
XinZhangMS 0:f7f1f0d76dd6 112 {
XinZhangMS 0:f7f1f0d76dd6 113 LogError("HTTPHeaders_Alloc failed");
XinZhangMS 0:f7f1f0d76dd6 114 }
XinZhangMS 0:f7f1f0d76dd6 115 else if (HTTPHeaders_AddHeaderNameValuePair(httpHeader, HTTP_HEADER_KEY_AUTHORIZATION, HTTP_HEADER_VAL_AUTHORIZATION) != HTTP_HEADERS_OK)
XinZhangMS 0:f7f1f0d76dd6 116 {
XinZhangMS 0:f7f1f0d76dd6 117 LogError("HTTPHeaders_AddHeaderNameValuePair failed for Authorization header");
XinZhangMS 0:f7f1f0d76dd6 118 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 119 httpHeader = NULL;
XinZhangMS 0:f7f1f0d76dd6 120 }
XinZhangMS 0:f7f1f0d76dd6 121 else if ((guid = generateGuid()) == NULL)
XinZhangMS 0:f7f1f0d76dd6 122 {
XinZhangMS 0:f7f1f0d76dd6 123 LogError("GUID creation failed");
XinZhangMS 0:f7f1f0d76dd6 124 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 125 httpHeader = NULL;
XinZhangMS 0:f7f1f0d76dd6 126 }
XinZhangMS 0:f7f1f0d76dd6 127 else if (HTTPHeaders_AddHeaderNameValuePair(httpHeader, HTTP_HEADER_KEY_REQUEST_ID, guid) != HTTP_HEADERS_OK)
XinZhangMS 0:f7f1f0d76dd6 128 {
XinZhangMS 0:f7f1f0d76dd6 129 LogError("HTTPHeaders_AddHeaderNameValuePair failed for RequestId header");
XinZhangMS 0:f7f1f0d76dd6 130 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 131 httpHeader = NULL;
XinZhangMS 0:f7f1f0d76dd6 132 }
XinZhangMS 0:f7f1f0d76dd6 133 else if (HTTPHeaders_AddHeaderNameValuePair(httpHeader, HTTP_HEADER_KEY_USER_AGENT, HTTP_HEADER_VAL_USER_AGENT) != HTTP_HEADERS_OK)
XinZhangMS 0:f7f1f0d76dd6 134 {
XinZhangMS 0:f7f1f0d76dd6 135 LogError("HTTPHeaders_AddHeaderNameValuePair failed for User-Agent header");
XinZhangMS 0:f7f1f0d76dd6 136 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 137 httpHeader = NULL;
XinZhangMS 0:f7f1f0d76dd6 138 }
XinZhangMS 0:f7f1f0d76dd6 139 else if (HTTPHeaders_AddHeaderNameValuePair(httpHeader, HTTP_HEADER_KEY_CONTENT_TYPE, HTTP_HEADER_VAL_CONTENT_TYPE) != HTTP_HEADERS_OK)
XinZhangMS 0:f7f1f0d76dd6 140 {
XinZhangMS 0:f7f1f0d76dd6 141 LogError("HTTPHeaders_AddHeaderNameValuePair failed for Content-Type header");
XinZhangMS 0:f7f1f0d76dd6 142 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 143 httpHeader = NULL;
XinZhangMS 0:f7f1f0d76dd6 144 }
XinZhangMS 0:f7f1f0d76dd6 145 else if (iotHubTwinRequestMode != IOTHUB_TWIN_REQUEST_GET)
XinZhangMS 0:f7f1f0d76dd6 146 {
XinZhangMS 0:f7f1f0d76dd6 147 if (HTTPHeaders_AddHeaderNameValuePair(httpHeader, HTTP_HEADER_KEY_IFMATCH, HTTP_HEADER_VAL_IFMATCH) != HTTP_HEADERS_OK)
XinZhangMS 0:f7f1f0d76dd6 148 {
XinZhangMS 0:f7f1f0d76dd6 149 LogError("HTTPHeaders_AddHeaderNameValuePair failed for If-Match header");
XinZhangMS 0:f7f1f0d76dd6 150 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 151 httpHeader = NULL;
XinZhangMS 0:f7f1f0d76dd6 152 }
XinZhangMS 0:f7f1f0d76dd6 153 }
XinZhangMS 0:f7f1f0d76dd6 154 free((void*)guid);
XinZhangMS 0:f7f1f0d76dd6 155
XinZhangMS 0:f7f1f0d76dd6 156 return httpHeader;
XinZhangMS 0:f7f1f0d76dd6 157 }
XinZhangMS 0:f7f1f0d76dd6 158
XinZhangMS 0:f7f1f0d76dd6 159 static IOTHUB_DEVICE_TWIN_RESULT sendHttpRequestTwin(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE serviceClientDeviceTwinHandle, IOTHUB_TWIN_REQUEST_MODE iotHubTwinRequestMode, const char* deviceName, const char* moduleId, BUFFER_HANDLE deviceJsonBuffer, BUFFER_HANDLE responseBuffer)
XinZhangMS 0:f7f1f0d76dd6 160 {
XinZhangMS 0:f7f1f0d76dd6 161 IOTHUB_DEVICE_TWIN_RESULT result;
XinZhangMS 0:f7f1f0d76dd6 162
XinZhangMS 0:f7f1f0d76dd6 163 STRING_HANDLE uriResource = NULL;
XinZhangMS 0:f7f1f0d76dd6 164 STRING_HANDLE accessKey = NULL;
XinZhangMS 0:f7f1f0d76dd6 165 STRING_HANDLE keyName = NULL;
XinZhangMS 0:f7f1f0d76dd6 166 HTTPAPIEX_SAS_HANDLE httpExApiSasHandle;
XinZhangMS 0:f7f1f0d76dd6 167 HTTPAPIEX_HANDLE httpExApiHandle;
XinZhangMS 0:f7f1f0d76dd6 168 HTTP_HEADERS_HANDLE httpHeader;
XinZhangMS 0:f7f1f0d76dd6 169
XinZhangMS 0:f7f1f0d76dd6 170 if ((uriResource = STRING_construct(serviceClientDeviceTwinHandle->hostname)) == NULL)
XinZhangMS 0:f7f1f0d76dd6 171 {
XinZhangMS 0:f7f1f0d76dd6 172 /*Codes_SRS_IOTHUBDEVICETWIN_12_024: [ If any of the HTTPAPI call fails IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 173 LogError("STRING_construct failed for uriResource");
XinZhangMS 0:f7f1f0d76dd6 174 result = IOTHUB_DEVICE_TWIN_ERROR;
XinZhangMS 0:f7f1f0d76dd6 175 }
XinZhangMS 0:f7f1f0d76dd6 176 else if ((accessKey = STRING_construct(serviceClientDeviceTwinHandle->sharedAccessKey)) == NULL)
XinZhangMS 0:f7f1f0d76dd6 177 {
XinZhangMS 0:f7f1f0d76dd6 178 /*Codes_SRS_IOTHUBDEVICETWIN_12_024: [ If any of the call fails during the HTTP creation IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 179 LogError("STRING_construct failed for accessKey");
XinZhangMS 0:f7f1f0d76dd6 180 STRING_delete(uriResource);
XinZhangMS 0:f7f1f0d76dd6 181 result = IOTHUB_DEVICE_TWIN_ERROR;
XinZhangMS 0:f7f1f0d76dd6 182 }
XinZhangMS 0:f7f1f0d76dd6 183 else if ((keyName = STRING_construct(serviceClientDeviceTwinHandle->keyName)) == NULL)
XinZhangMS 0:f7f1f0d76dd6 184 {
XinZhangMS 0:f7f1f0d76dd6 185 /*Codes_SRS_IOTHUBDEVICETWIN_12_024: [ If any of the call fails during the HTTP creation IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 186 LogError("STRING_construct failed for keyName");
XinZhangMS 0:f7f1f0d76dd6 187 STRING_delete(accessKey);
XinZhangMS 0:f7f1f0d76dd6 188 STRING_delete(uriResource);
XinZhangMS 0:f7f1f0d76dd6 189 result = IOTHUB_DEVICE_TWIN_ERROR;
XinZhangMS 0:f7f1f0d76dd6 190 }
XinZhangMS 0:f7f1f0d76dd6 191 /*Codes_SRS_IOTHUBDEVICETWIN_12_020: [ IoTHubDeviceTwin_GetTwin shall add the following headers to the created HTTP GET request: authorization=sasToken,Request-Id=1001,Accept=application/json,Content-Type=application/json,charset=utf-8 ]*/
XinZhangMS 0:f7f1f0d76dd6 192 else if ((httpHeader = createHttpHeader(iotHubTwinRequestMode)) == NULL)
XinZhangMS 0:f7f1f0d76dd6 193 {
XinZhangMS 0:f7f1f0d76dd6 194 /*Codes_SRS_IOTHUBDEVICETWIN_12_024: [ If any of the call fails during the HTTP creation IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 195 LogError("HttpHeader creation failed");
XinZhangMS 0:f7f1f0d76dd6 196 STRING_delete(keyName);
XinZhangMS 0:f7f1f0d76dd6 197 STRING_delete(accessKey);
XinZhangMS 0:f7f1f0d76dd6 198 STRING_delete(uriResource);
XinZhangMS 0:f7f1f0d76dd6 199 result = IOTHUB_DEVICE_TWIN_ERROR;
XinZhangMS 0:f7f1f0d76dd6 200 }
XinZhangMS 0:f7f1f0d76dd6 201 /*Codes_SRS_IOTHUBDEVICETWIN_12_021: [ IoTHubDeviceTwin_GetTwin shall create an HTTPAPIEX_SAS_HANDLE handle by calling HTTPAPIEX_SAS_Create ]*/
XinZhangMS 0:f7f1f0d76dd6 202 else if ((httpExApiSasHandle = HTTPAPIEX_SAS_Create(accessKey, uriResource, keyName)) == NULL)
XinZhangMS 0:f7f1f0d76dd6 203 {
XinZhangMS 0:f7f1f0d76dd6 204 /*Codes_SRS_IOTHUBDEVICETWIN_12_025: [ If any of the HTTPAPI call fails IoTHubDeviceTwin_GetTwin shall fail and return IOTHUB_DEVICE_TWIN_HTTPAPI_ERROR ]*/
XinZhangMS 0:f7f1f0d76dd6 205 LogError("HTTPAPIEX_SAS_Create failed");
XinZhangMS 0:f7f1f0d76dd6 206 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 207 STRING_delete(keyName);
XinZhangMS 0:f7f1f0d76dd6 208 STRING_delete(accessKey);
XinZhangMS 0:f7f1f0d76dd6 209 STRING_delete(uriResource);
XinZhangMS 0:f7f1f0d76dd6 210 result = IOTHUB_DEVICE_TWIN_HTTPAPI_ERROR;
XinZhangMS 0:f7f1f0d76dd6 211 }
XinZhangMS 0:f7f1f0d76dd6 212 /*Codes_SRS_IOTHUBDEVICETWIN_12_022: [ IoTHubDeviceTwin_GetTwin shall create an HTTPAPIEX_HANDLE handle by calling HTTPAPIEX_Create ]*/
XinZhangMS 0:f7f1f0d76dd6 213 else if ((httpExApiHandle = HTTPAPIEX_Create(serviceClientDeviceTwinHandle->hostname)) == NULL)
XinZhangMS 0:f7f1f0d76dd6 214 {
XinZhangMS 0:f7f1f0d76dd6 215 /*Codes_SRS_IOTHUBDEVICETWIN_12_025: [ If any of the HTTPAPI call fails IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 216 LogError("HTTPAPIEX_Create failed");
XinZhangMS 0:f7f1f0d76dd6 217 HTTPAPIEX_SAS_Destroy(httpExApiSasHandle);
XinZhangMS 0:f7f1f0d76dd6 218 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 219 STRING_delete(keyName);
XinZhangMS 0:f7f1f0d76dd6 220 STRING_delete(accessKey);
XinZhangMS 0:f7f1f0d76dd6 221 STRING_delete(uriResource);
XinZhangMS 0:f7f1f0d76dd6 222 result = IOTHUB_DEVICE_TWIN_HTTPAPI_ERROR;
XinZhangMS 0:f7f1f0d76dd6 223 }
XinZhangMS 0:f7f1f0d76dd6 224 else
XinZhangMS 0:f7f1f0d76dd6 225 {
XinZhangMS 0:f7f1f0d76dd6 226 HTTPAPI_REQUEST_TYPE httpApiRequestType = HTTPAPI_REQUEST_GET;
XinZhangMS 0:f7f1f0d76dd6 227 STRING_HANDLE relativePath;
XinZhangMS 0:f7f1f0d76dd6 228 unsigned int statusCode = 0;
XinZhangMS 0:f7f1f0d76dd6 229 unsigned char is_error = 0;
XinZhangMS 0:f7f1f0d76dd6 230
XinZhangMS 0:f7f1f0d76dd6 231 //IOTHUB_TWIN_REQUEST_GET GET {iot hub}/twins/{device id} // Get device twin
XinZhangMS 0:f7f1f0d76dd6 232 //IOTHUB_TWIN_REQUEST_UPDATE PATCH {iot hub}/twins/{device id} // Partally update device twin
XinZhangMS 0:f7f1f0d76dd6 233 //IOTHUB_TWIN_REQUEST_REPLACE_TAGS PUT {iot hub}/twins/{device id}/tags // Replace update tags
XinZhangMS 0:f7f1f0d76dd6 234 //IOTHUB_TWIN_REQUEST_REPLACE_DESIRED PUT {iot hub}/twins/{device id}/properties/desired // Replace update desired properties
XinZhangMS 0:f7f1f0d76dd6 235 //IOTHUB_TWIN_REQUEST_UPDATE_DESIRED PATCH {iot hub}/twins/{device id}/properties/desired // Partially update desired properties
XinZhangMS 0:f7f1f0d76dd6 236
XinZhangMS 0:f7f1f0d76dd6 237 if ((iotHubTwinRequestMode == IOTHUB_TWIN_REQUEST_REPLACE_TAGS) || (iotHubTwinRequestMode == IOTHUB_TWIN_REQUEST_REPLACE_DESIRED))
XinZhangMS 0:f7f1f0d76dd6 238 {
XinZhangMS 0:f7f1f0d76dd6 239 httpApiRequestType = HTTPAPI_REQUEST_PUT;
XinZhangMS 0:f7f1f0d76dd6 240 }
XinZhangMS 0:f7f1f0d76dd6 241 else if ((iotHubTwinRequestMode == IOTHUB_TWIN_REQUEST_UPDATE) || (iotHubTwinRequestMode == IOTHUB_TWIN_REQUEST_UPDATE_DESIRED))
XinZhangMS 0:f7f1f0d76dd6 242 {
XinZhangMS 0:f7f1f0d76dd6 243 httpApiRequestType = HTTPAPI_REQUEST_PATCH;
XinZhangMS 0:f7f1f0d76dd6 244 }
XinZhangMS 0:f7f1f0d76dd6 245 else if (iotHubTwinRequestMode == IOTHUB_TWIN_REQUEST_GET)
XinZhangMS 0:f7f1f0d76dd6 246 {
XinZhangMS 0:f7f1f0d76dd6 247 httpApiRequestType = HTTPAPI_REQUEST_GET;
XinZhangMS 0:f7f1f0d76dd6 248 }
XinZhangMS 0:f7f1f0d76dd6 249 else
XinZhangMS 0:f7f1f0d76dd6 250 {
XinZhangMS 0:f7f1f0d76dd6 251 is_error = 1;
XinZhangMS 0:f7f1f0d76dd6 252 }
XinZhangMS 0:f7f1f0d76dd6 253
XinZhangMS 0:f7f1f0d76dd6 254 if (is_error)
XinZhangMS 0:f7f1f0d76dd6 255 {
XinZhangMS 0:f7f1f0d76dd6 256 LogError("Invalid request type");
XinZhangMS 0:f7f1f0d76dd6 257 result = IOTHUB_DEVICE_TWIN_HTTPAPI_ERROR;
XinZhangMS 0:f7f1f0d76dd6 258 }
XinZhangMS 0:f7f1f0d76dd6 259 else
XinZhangMS 0:f7f1f0d76dd6 260 {
XinZhangMS 0:f7f1f0d76dd6 261 /*Codes_SRS_IOTHUBDEVICETWIN_12_019: [ IoTHubDeviceTwin_GetTwin shall create HTTP GET request URL using the given deviceId using the following format: url/twins/[deviceId] ]*/
XinZhangMS 0:f7f1f0d76dd6 262 if ((relativePath = createRelativePath(iotHubTwinRequestMode, deviceName, moduleId)) == NULL)
XinZhangMS 0:f7f1f0d76dd6 263 {
XinZhangMS 0:f7f1f0d76dd6 264 /*Codes_SRS_IOTHUBDEVICETWIN_12_024: [ If any of the call fails during the HTTP creation IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 265 LogError("Failure creating relative path");
XinZhangMS 0:f7f1f0d76dd6 266 result = IOTHUB_DEVICE_TWIN_ERROR;
XinZhangMS 0:f7f1f0d76dd6 267 }
XinZhangMS 0:f7f1f0d76dd6 268 /*Codes_SRS_IOTHUBDEVICETWIN_12_023: [ IoTHubDeviceTwin_GetTwin shall execute the HTTP GET request by calling HTTPAPIEX_ExecuteRequest ]*/
XinZhangMS 0:f7f1f0d76dd6 269 else if (HTTPAPIEX_SAS_ExecuteRequest(httpExApiSasHandle, httpExApiHandle, httpApiRequestType, STRING_c_str(relativePath), httpHeader, deviceJsonBuffer, &statusCode, NULL, responseBuffer) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 270 {
XinZhangMS 0:f7f1f0d76dd6 271 /*Codes_SRS_IOTHUBDEVICETWIN_12_025: [ If any of the HTTPAPI call fails IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 272 LogError("HTTPAPIEX_SAS_ExecuteRequest failed");
XinZhangMS 0:f7f1f0d76dd6 273 STRING_delete(relativePath);
XinZhangMS 0:f7f1f0d76dd6 274 result = IOTHUB_DEVICE_TWIN_HTTPAPI_ERROR;
XinZhangMS 0:f7f1f0d76dd6 275 }
XinZhangMS 0:f7f1f0d76dd6 276 else
XinZhangMS 0:f7f1f0d76dd6 277 {
XinZhangMS 0:f7f1f0d76dd6 278 STRING_delete(relativePath);
XinZhangMS 0:f7f1f0d76dd6 279 if (statusCode == 200)
XinZhangMS 0:f7f1f0d76dd6 280 {
XinZhangMS 0:f7f1f0d76dd6 281 /*CodesSRS_IOTHUBDEVICETWIN_12_030: [ Otherwise IoTHubDeviceTwin_GetTwin shall save the received deviceTwin to the out parameter and return with it ]*/
XinZhangMS 0:f7f1f0d76dd6 282 result = IOTHUB_DEVICE_TWIN_OK;
XinZhangMS 0:f7f1f0d76dd6 283 }
XinZhangMS 0:f7f1f0d76dd6 284 else
XinZhangMS 0:f7f1f0d76dd6 285 {
XinZhangMS 0:f7f1f0d76dd6 286 /*Codes_SRS_IOTHUBDEVICETWIN_12_026: [ IoTHubDeviceTwin_GetTwin shall verify the received HTTP status code and if it is not equal to 200 then return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 287 LogError("Http Failure status code %d.", statusCode);
XinZhangMS 0:f7f1f0d76dd6 288 result = IOTHUB_DEVICE_TWIN_ERROR;
XinZhangMS 0:f7f1f0d76dd6 289 }
XinZhangMS 0:f7f1f0d76dd6 290 }
XinZhangMS 0:f7f1f0d76dd6 291 }
XinZhangMS 0:f7f1f0d76dd6 292 HTTPAPIEX_Destroy(httpExApiHandle);
XinZhangMS 0:f7f1f0d76dd6 293 HTTPAPIEX_SAS_Destroy(httpExApiSasHandle);
XinZhangMS 0:f7f1f0d76dd6 294 HTTPHeaders_Free(httpHeader);
XinZhangMS 0:f7f1f0d76dd6 295 STRING_delete(keyName);
XinZhangMS 0:f7f1f0d76dd6 296 STRING_delete(accessKey);
XinZhangMS 0:f7f1f0d76dd6 297 STRING_delete(uriResource);
XinZhangMS 0:f7f1f0d76dd6 298 }
XinZhangMS 0:f7f1f0d76dd6 299 return result;
XinZhangMS 0:f7f1f0d76dd6 300 }
XinZhangMS 0:f7f1f0d76dd6 301
XinZhangMS 0:f7f1f0d76dd6 302 static void free_devicetwin_handle(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN* deviceTwin)
XinZhangMS 0:f7f1f0d76dd6 303 {
XinZhangMS 0:f7f1f0d76dd6 304 free(deviceTwin->hostname);
XinZhangMS 0:f7f1f0d76dd6 305 free(deviceTwin->sharedAccessKey);
XinZhangMS 0:f7f1f0d76dd6 306 free(deviceTwin->keyName);
XinZhangMS 0:f7f1f0d76dd6 307 free(deviceTwin);
XinZhangMS 0:f7f1f0d76dd6 308 }
XinZhangMS 0:f7f1f0d76dd6 309
XinZhangMS 0:f7f1f0d76dd6 310 IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE IoTHubDeviceTwin_Create(IOTHUB_SERVICE_CLIENT_AUTH_HANDLE serviceClientHandle)
XinZhangMS 0:f7f1f0d76dd6 311 {
XinZhangMS 0:f7f1f0d76dd6 312 IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE result;
XinZhangMS 0:f7f1f0d76dd6 313
XinZhangMS 0:f7f1f0d76dd6 314 /*Codes_SRS_IOTHUBDEVICETWIN_12_001: [ If the serviceClientHandle input parameter is NULL IoTHubDeviceTwin_Create shall return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 315 if (serviceClientHandle == NULL)
XinZhangMS 0:f7f1f0d76dd6 316 {
XinZhangMS 0:f7f1f0d76dd6 317 LogError("serviceClientHandle input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 318 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 319 }
XinZhangMS 0:f7f1f0d76dd6 320 else
XinZhangMS 0:f7f1f0d76dd6 321 {
XinZhangMS 0:f7f1f0d76dd6 322 /*Codes_SRS_IOTHUBDEVICETWIN_12_002: [ If any member of the serviceClientHandle input parameter is NULL IoTHubDeviceTwin_Create shall return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 323 IOTHUB_SERVICE_CLIENT_AUTH* serviceClientAuth = (IOTHUB_SERVICE_CLIENT_AUTH*)serviceClientHandle;
XinZhangMS 0:f7f1f0d76dd6 324
XinZhangMS 0:f7f1f0d76dd6 325 if (serviceClientAuth->hostname == NULL)
XinZhangMS 0:f7f1f0d76dd6 326 {
XinZhangMS 0:f7f1f0d76dd6 327 LogError("authInfo->hostName input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 328 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 329 }
XinZhangMS 0:f7f1f0d76dd6 330 else if (serviceClientAuth->iothubName == NULL)
XinZhangMS 0:f7f1f0d76dd6 331 {
XinZhangMS 0:f7f1f0d76dd6 332 LogError("authInfo->iothubName input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 333 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 334 }
XinZhangMS 0:f7f1f0d76dd6 335 else if (serviceClientAuth->iothubSuffix == NULL)
XinZhangMS 0:f7f1f0d76dd6 336 {
XinZhangMS 0:f7f1f0d76dd6 337 LogError("authInfo->iothubSuffix input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 338 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 339 }
XinZhangMS 0:f7f1f0d76dd6 340 else if (serviceClientAuth->keyName == NULL)
XinZhangMS 0:f7f1f0d76dd6 341 {
XinZhangMS 0:f7f1f0d76dd6 342 LogError("authInfo->keyName input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 343 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 344 }
XinZhangMS 0:f7f1f0d76dd6 345 else if (serviceClientAuth->sharedAccessKey == NULL)
XinZhangMS 0:f7f1f0d76dd6 346 {
XinZhangMS 0:f7f1f0d76dd6 347 LogError("authInfo->sharedAccessKey input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 348 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 349 }
XinZhangMS 0:f7f1f0d76dd6 350 else
XinZhangMS 0:f7f1f0d76dd6 351 {
XinZhangMS 0:f7f1f0d76dd6 352 /*Codes_SRS_IOTHUBDEVICETWIN_12_003: [ IoTHubDeviceTwin_Create shall allocate memory for a new IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE instance ]*/
XinZhangMS 0:f7f1f0d76dd6 353 result = malloc(sizeof(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN));
XinZhangMS 0:f7f1f0d76dd6 354 if (result == NULL)
XinZhangMS 0:f7f1f0d76dd6 355 {
XinZhangMS 0:f7f1f0d76dd6 356 /*Codes_SRS_IOTHUBDEVICETWIN_12_004: [ If the allocation failed, IoTHubDeviceTwin_Create shall return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 357 LogError("Malloc failed for IOTHUB_SERVICE_CLIENT_DEVICE_TWIN");
XinZhangMS 0:f7f1f0d76dd6 358 }
XinZhangMS 0:f7f1f0d76dd6 359 else
XinZhangMS 0:f7f1f0d76dd6 360 {
XinZhangMS 0:f7f1f0d76dd6 361 memset(result, 0, sizeof(*result));
XinZhangMS 0:f7f1f0d76dd6 362
XinZhangMS 0:f7f1f0d76dd6 363 /*Codes_SRS_IOTHUBDEVICETWIN_12_005: [ If the allocation successful, IoTHubDeviceTwin_Create shall create a IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE from the given IOTHUB_SERVICE_CLIENT_AUTH_HANDLE and return with it ]*/
XinZhangMS 0:f7f1f0d76dd6 364 /*Codes_SRS_IOTHUBDEVICETWIN_12_006: [ IoTHubDeviceTwin_Create shall allocate memory and copy hostName to result->hostName by calling mallocAndStrcpy_s. ]*/
XinZhangMS 0:f7f1f0d76dd6 365 if (mallocAndStrcpy_s(&result->hostname, serviceClientAuth->hostname) != 0)
XinZhangMS 0:f7f1f0d76dd6 366 {
XinZhangMS 0:f7f1f0d76dd6 367 /*Codes_SRS_IOTHUBDEVICETWIN_12_007: [ If the mallocAndStrcpy_s fails, IoTHubDeviceTwin_Create shall do clean up and return NULL. ]*/
XinZhangMS 0:f7f1f0d76dd6 368 LogError("mallocAndStrcpy_s failed for hostName");
XinZhangMS 0:f7f1f0d76dd6 369 free_devicetwin_handle(result);
XinZhangMS 0:f7f1f0d76dd6 370 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 371 }
XinZhangMS 0:f7f1f0d76dd6 372 /*Codes_SRS_IOTHUBDEVICETWIN_12_012: [ IoTHubDeviceTwin_Create shall allocate memory and copy sharedAccessKey to result->sharedAccessKey by calling mallocAndStrcpy_s. ]*/
XinZhangMS 0:f7f1f0d76dd6 373 else if (mallocAndStrcpy_s(&result->sharedAccessKey, serviceClientAuth->sharedAccessKey) != 0)
XinZhangMS 0:f7f1f0d76dd6 374 {
XinZhangMS 0:f7f1f0d76dd6 375 /*Codes_SRS_IOTHUBDEVICETWIN_12_013: [ If the mallocAndStrcpy_s fails, IoTHubDeviceTwin_Create shall do clean up and return NULL. ]*/
XinZhangMS 0:f7f1f0d76dd6 376 LogError("mallocAndStrcpy_s failed for sharedAccessKey");
XinZhangMS 0:f7f1f0d76dd6 377 free_devicetwin_handle(result);
XinZhangMS 0:f7f1f0d76dd6 378 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 379 }
XinZhangMS 0:f7f1f0d76dd6 380 /*Codes_SRS_IOTHUBDEVICETWIN_12_014: [ IoTHubDeviceTwin_Create shall allocate memory and copy keyName to result->keyName by calling mallocAndStrcpy_s. ]*/
XinZhangMS 0:f7f1f0d76dd6 381 else if (mallocAndStrcpy_s(&result->keyName, serviceClientAuth->keyName) != 0)
XinZhangMS 0:f7f1f0d76dd6 382 {
XinZhangMS 0:f7f1f0d76dd6 383 /*Codes_SRS_IOTHUBDEVICETWIN_12_015: [ If the mallocAndStrcpy_s fails, IoTHubDeviceTwin_Create shall do clean up and return NULL. ]*/
XinZhangMS 0:f7f1f0d76dd6 384 LogError("mallocAndStrcpy_s failed for keyName");
XinZhangMS 0:f7f1f0d76dd6 385 free_devicetwin_handle(result);
XinZhangMS 0:f7f1f0d76dd6 386 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 387 }
XinZhangMS 0:f7f1f0d76dd6 388 }
XinZhangMS 0:f7f1f0d76dd6 389 }
XinZhangMS 0:f7f1f0d76dd6 390 }
XinZhangMS 0:f7f1f0d76dd6 391 return result;
XinZhangMS 0:f7f1f0d76dd6 392 }
XinZhangMS 0:f7f1f0d76dd6 393
XinZhangMS 0:f7f1f0d76dd6 394 void IoTHubDeviceTwin_Destroy(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE serviceClientDeviceTwinHandle)
XinZhangMS 0:f7f1f0d76dd6 395 {
XinZhangMS 0:f7f1f0d76dd6 396 /*Codes_SRS_IOTHUBDEVICETWIN_12_016: [ If the serviceClientDeviceTwinHandle input parameter is NULL IoTHubDeviceTwin_Destroy shall return ]*/
XinZhangMS 0:f7f1f0d76dd6 397 if (serviceClientDeviceTwinHandle != NULL)
XinZhangMS 0:f7f1f0d76dd6 398 {
XinZhangMS 0:f7f1f0d76dd6 399 /*Codes_SRS_IOTHUBDEVICETWIN_12_017: [ If the serviceClientDeviceTwinHandle input parameter is not NULL IoTHubDeviceTwin_Destroy shall free the memory of it and return ]*/
XinZhangMS 0:f7f1f0d76dd6 400 free_devicetwin_handle((IOTHUB_SERVICE_CLIENT_DEVICE_TWIN*)serviceClientDeviceTwinHandle);
XinZhangMS 0:f7f1f0d76dd6 401 }
XinZhangMS 0:f7f1f0d76dd6 402 }
XinZhangMS 0:f7f1f0d76dd6 403
XinZhangMS 0:f7f1f0d76dd6 404 static int malloc_and_copy_uchar(char** strDestination, BUFFER_HANDLE strSource)
XinZhangMS 0:f7f1f0d76dd6 405 {
XinZhangMS 0:f7f1f0d76dd6 406 int result;
XinZhangMS 0:f7f1f0d76dd6 407 if ((strDestination == NULL) || (strSource == NULL))
XinZhangMS 0:f7f1f0d76dd6 408 {
XinZhangMS 0:f7f1f0d76dd6 409 /* If strDestination or strSource is a NULL pointer[...] function return line number where error is spotted */
XinZhangMS 0:f7f1f0d76dd6 410 LogError("invalid parameter strDestination or strSource");
XinZhangMS 0:f7f1f0d76dd6 411 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 412 }
XinZhangMS 0:f7f1f0d76dd6 413 else
XinZhangMS 0:f7f1f0d76dd6 414 {
XinZhangMS 0:f7f1f0d76dd6 415 size_t buffer_size = BUFFER_length(strSource);
XinZhangMS 0:f7f1f0d76dd6 416 char *temp = malloc(buffer_size + 1);
XinZhangMS 0:f7f1f0d76dd6 417 if (temp == NULL)
XinZhangMS 0:f7f1f0d76dd6 418 {
XinZhangMS 0:f7f1f0d76dd6 419 LogError("failed to malloc");
XinZhangMS 0:f7f1f0d76dd6 420 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 421 }
XinZhangMS 0:f7f1f0d76dd6 422 else
XinZhangMS 0:f7f1f0d76dd6 423 {
XinZhangMS 0:f7f1f0d76dd6 424 *strDestination = memcpy(temp, BUFFER_u_char(strSource), buffer_size);
XinZhangMS 0:f7f1f0d76dd6 425 temp[buffer_size] = '\0';
XinZhangMS 0:f7f1f0d76dd6 426 result = 0;
XinZhangMS 0:f7f1f0d76dd6 427 }
XinZhangMS 0:f7f1f0d76dd6 428 }
XinZhangMS 0:f7f1f0d76dd6 429 return result;
XinZhangMS 0:f7f1f0d76dd6 430 }
XinZhangMS 0:f7f1f0d76dd6 431
XinZhangMS 0:f7f1f0d76dd6 432 char* IoTHubDeviceTwin_GetDeviceOrModuleTwin(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE serviceClientDeviceTwinHandle, const char* deviceId, const char* moduleId)
XinZhangMS 0:f7f1f0d76dd6 433 {
XinZhangMS 0:f7f1f0d76dd6 434 char* result;
XinZhangMS 0:f7f1f0d76dd6 435
XinZhangMS 0:f7f1f0d76dd6 436 /*Codes_SRS_IOTHUBDEVICETWIN_12_018: [ IoTHubDeviceTwin_GetTwin shall verify the input parameters and if any of them are NULL then return IOTHUB_DEVICE_TWIN_INVALID_ARG ]*/
XinZhangMS 0:f7f1f0d76dd6 437 if ((serviceClientDeviceTwinHandle == NULL) || (deviceId == NULL))
XinZhangMS 0:f7f1f0d76dd6 438 {
XinZhangMS 0:f7f1f0d76dd6 439 LogError("Input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 440 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 441 }
XinZhangMS 0:f7f1f0d76dd6 442 else
XinZhangMS 0:f7f1f0d76dd6 443 {
XinZhangMS 0:f7f1f0d76dd6 444 BUFFER_HANDLE responseBuffer;
XinZhangMS 0:f7f1f0d76dd6 445
XinZhangMS 0:f7f1f0d76dd6 446 if ((responseBuffer = BUFFER_new()) == NULL)
XinZhangMS 0:f7f1f0d76dd6 447 {
XinZhangMS 0:f7f1f0d76dd6 448 LogError("BUFFER_new failed for responseBuffer");
XinZhangMS 0:f7f1f0d76dd6 449 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 450 }
XinZhangMS 0:f7f1f0d76dd6 451 /*Codes_SRS_IOTHUBDEVICETWIN_12_019: [ IoTHubDeviceTwin_GetTwin shall create HTTP GET request URL using the given deviceId using the following format: url/twins/[deviceId] ]*/
XinZhangMS 0:f7f1f0d76dd6 452 /*Codes_SRS_IOTHUBDEVICETWIN_12_020: [ IoTHubDeviceTwin_GetTwin shall add the following headers to the created HTTP GET request: authorization=sasToken,Request-Id=1001,Accept=application/json,Content-Type=application/json,charset=utf-8 ]*/
XinZhangMS 0:f7f1f0d76dd6 453 /*Codes_SRS_IOTHUBDEVICETWIN_12_021: [ IoTHubDeviceTwin_GetTwin shall create an HTTPAPIEX_SAS_HANDLE handle by calling HTTPAPIEX_SAS_Create ]*/
XinZhangMS 0:f7f1f0d76dd6 454 /*Codes_SRS_IOTHUBDEVICETWIN_12_022: [ IoTHubDeviceTwin_GetTwin shall create an HTTPAPIEX_HANDLE handle by calling HTTPAPIEX_Create ]*/
XinZhangMS 0:f7f1f0d76dd6 455 /*Codes_SRS_IOTHUBDEVICETWIN_12_023: [ IoTHubDeviceTwin_GetTwin shall execute the HTTP GET request by calling HTTPAPIEX_ExecuteRequest ]*/
XinZhangMS 0:f7f1f0d76dd6 456 else if (sendHttpRequestTwin(serviceClientDeviceTwinHandle, IOTHUB_TWIN_REQUEST_GET, deviceId, moduleId, NULL, responseBuffer) != IOTHUB_DEVICE_TWIN_OK)
XinZhangMS 0:f7f1f0d76dd6 457 {
XinZhangMS 0:f7f1f0d76dd6 458 /*Codes_SRS_IOTHUBDEVICETWIN_12_024: [ If any of the call fails during the HTTP creation IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 459 /*Codes_SRS_IOTHUBDEVICETWIN_12_025: [ If any of the HTTPAPI call fails IoTHubDeviceTwin_GetTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 460 LogError("Failure sending HTTP request for create device");
XinZhangMS 0:f7f1f0d76dd6 461 BUFFER_delete(responseBuffer);
XinZhangMS 0:f7f1f0d76dd6 462 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 463 }
XinZhangMS 0:f7f1f0d76dd6 464 else
XinZhangMS 0:f7f1f0d76dd6 465 {
XinZhangMS 0:f7f1f0d76dd6 466 /*Codes_SRS_IOTHUBDEVICETWIN_12_030: [ Otherwise IoTHubDeviceTwin_GetTwin shall save the received `deviceTwin` to the out parameter and return with it ]*/
XinZhangMS 0:f7f1f0d76dd6 467 if (malloc_and_copy_uchar(&result, responseBuffer) != 0)
XinZhangMS 0:f7f1f0d76dd6 468 {
XinZhangMS 0:f7f1f0d76dd6 469 LogError("failed to copy response");
XinZhangMS 0:f7f1f0d76dd6 470 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 471 }
XinZhangMS 0:f7f1f0d76dd6 472 BUFFER_delete(responseBuffer);
XinZhangMS 0:f7f1f0d76dd6 473 }
XinZhangMS 0:f7f1f0d76dd6 474 }
XinZhangMS 0:f7f1f0d76dd6 475 return result;
XinZhangMS 0:f7f1f0d76dd6 476
XinZhangMS 0:f7f1f0d76dd6 477 }
XinZhangMS 0:f7f1f0d76dd6 478
XinZhangMS 0:f7f1f0d76dd6 479 char* IoTHubDeviceTwin_GetTwin(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE serviceClientDeviceTwinHandle, const char* deviceId)
XinZhangMS 0:f7f1f0d76dd6 480 {
XinZhangMS 0:f7f1f0d76dd6 481 return IoTHubDeviceTwin_GetDeviceOrModuleTwin(serviceClientDeviceTwinHandle, deviceId, NULL);
XinZhangMS 0:f7f1f0d76dd6 482 }
XinZhangMS 0:f7f1f0d76dd6 483
XinZhangMS 0:f7f1f0d76dd6 484 char* IoTHubDeviceTwin_GetModuleTwin(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE serviceClientDeviceTwinHandle, const char* deviceId, const char* moduleId)
XinZhangMS 0:f7f1f0d76dd6 485 {
XinZhangMS 0:f7f1f0d76dd6 486 char* result;
XinZhangMS 0:f7f1f0d76dd6 487 if ((serviceClientDeviceTwinHandle == NULL) || (deviceId == NULL) || (moduleId == NULL))
XinZhangMS 0:f7f1f0d76dd6 488 {
XinZhangMS 0:f7f1f0d76dd6 489 LogError("Input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 490 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 491 }
XinZhangMS 0:f7f1f0d76dd6 492 else
XinZhangMS 0:f7f1f0d76dd6 493 {
XinZhangMS 0:f7f1f0d76dd6 494 result = IoTHubDeviceTwin_GetDeviceOrModuleTwin(serviceClientDeviceTwinHandle, deviceId, moduleId);
XinZhangMS 0:f7f1f0d76dd6 495 }
XinZhangMS 0:f7f1f0d76dd6 496
XinZhangMS 0:f7f1f0d76dd6 497 return result;
XinZhangMS 0:f7f1f0d76dd6 498 }
XinZhangMS 0:f7f1f0d76dd6 499
XinZhangMS 0:f7f1f0d76dd6 500 char* IoTHubDeviceTwin_UpdateDeviceOrModuleTwin(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE serviceClientDeviceTwinHandle, const char* deviceId, const char* moduleId, const char* deviceTwinJson)
XinZhangMS 0:f7f1f0d76dd6 501 {
XinZhangMS 0:f7f1f0d76dd6 502 char* result;
XinZhangMS 0:f7f1f0d76dd6 503
XinZhangMS 0:f7f1f0d76dd6 504 /*CodesSRS_IOTHUBDEVICETWIN_12_031: [ IoTHubDeviceTwin_UpdateTwin shall verify the input parameters and if any of them are NULL then return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 505 if ((serviceClientDeviceTwinHandle == NULL) || (deviceId == NULL) || (deviceTwinJson == NULL))
XinZhangMS 0:f7f1f0d76dd6 506 {
XinZhangMS 0:f7f1f0d76dd6 507 LogError("Input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 508 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 509 }
XinZhangMS 0:f7f1f0d76dd6 510 else
XinZhangMS 0:f7f1f0d76dd6 511 {
XinZhangMS 0:f7f1f0d76dd6 512 BUFFER_HANDLE updateJson;
XinZhangMS 0:f7f1f0d76dd6 513 BUFFER_HANDLE responseBuffer;
XinZhangMS 0:f7f1f0d76dd6 514
XinZhangMS 0:f7f1f0d76dd6 515 /*CodesSRS_IOTHUBDEVICETWIN_12_032: [ IoTHubDeviceTwin_UpdateTwin shall create a BUFFER_HANDLE from deviceTwinJson by calling BUFFER_create ]*/
XinZhangMS 0:f7f1f0d76dd6 516 if ((updateJson = BUFFER_create((const unsigned char*)deviceTwinJson, strlen(deviceTwinJson))) == NULL)
XinZhangMS 0:f7f1f0d76dd6 517 {
XinZhangMS 0:f7f1f0d76dd6 518 /*CodesSRS_IOTHUBDEVICETWIN_12_033: [ If the creation fails, IoTHubDeviceTwin_UpdateTwin shall return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 519 LogError("BUFFER_create failed for deviceTwinJson");
XinZhangMS 0:f7f1f0d76dd6 520 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 521 }
XinZhangMS 0:f7f1f0d76dd6 522 /*CodesSRS_IOTHUBDEVICETWIN_12_034: [ IoTHubDeviceTwin_UpdateTwin shall allocate memory for response buffer by calling BUFFER_new ]*/
XinZhangMS 0:f7f1f0d76dd6 523 /*CodesSRS_IOTHUBDEVICETWIN_12_035: [ If the allocation failed, IoTHubDeviceTwin_UpdateTwin shall return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 524 else if ((responseBuffer = BUFFER_new()) == NULL)
XinZhangMS 0:f7f1f0d76dd6 525 {
XinZhangMS 0:f7f1f0d76dd6 526 /*CodesSRS_IOTHUBDEVICETWIN_12_034: [ If the creation fails, IoTHubDeviceTwin_UpdateTwin shall return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 527 LogError("BUFFER_new failed for responseBuffer");
XinZhangMS 0:f7f1f0d76dd6 528 BUFFER_delete(updateJson);
XinZhangMS 0:f7f1f0d76dd6 529 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 530 }
XinZhangMS 0:f7f1f0d76dd6 531 /*CodesSRS_IOTHUBDEVICETWIN_12_039: [ IoTHubDeviceTwin_UpdateTwin shall create an HTTP PATCH request using deviceTwinJson ]*/
XinZhangMS 0:f7f1f0d76dd6 532 /*CodesSRS_IOTHUBDEVICETWIN_12_040: [ IoTHubDeviceTwin_UpdateTwin shall create an HTTP PATCH request using the createdfollowing HTTP headers: authorization=sasToken,Request-Id=1001,Accept=application/json,Content-Type=application/json,charset=utf-8 ]*/
XinZhangMS 0:f7f1f0d76dd6 533 /*CodesSRS_IOTHUBDEVICETWIN_12_041: [ IoTHubDeviceTwin_UpdateTwin shall create an HTTPAPIEX_SAS_HANDLE handle by calling HTTPAPIEX_SAS_Create ]*/
XinZhangMS 0:f7f1f0d76dd6 534 /*CodesSRS_IOTHUBDEVICETWIN_12_042: [ IoTHubDeviceTwin_UpdateTwin shall create an HTTPAPIEX_HANDLE handle by calling HTTPAPIEX_Create ]*/
XinZhangMS 0:f7f1f0d76dd6 535 /*CodesSRS_IOTHUBDEVICETWIN_12_043: [ IoTHubDeviceTwin_UpdateTwin shall execute the HTTP PATCH request by calling HTTPAPIEX_ExecuteRequest ]*/
XinZhangMS 0:f7f1f0d76dd6 536 else if (sendHttpRequestTwin(serviceClientDeviceTwinHandle, IOTHUB_TWIN_REQUEST_UPDATE, deviceId, moduleId, updateJson, responseBuffer) != IOTHUB_DEVICE_TWIN_OK)
XinZhangMS 0:f7f1f0d76dd6 537 {
XinZhangMS 0:f7f1f0d76dd6 538 /*CodesSRS_IOTHUBDEVICETWIN_12_044: [ If any of the call fails during the HTTP creation IoTHubDeviceTwin_UpdateTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 539 /*CodesSRS_IOTHUBDEVICETWIN_12_045: [ If any of the HTTPAPI call fails IoTHubDeviceTwin_UpdateTwin shall fail and return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 540 /*CodesSRS_IOTHUBDEVICETWIN_12_046: [ IoTHubDeviceTwin_UpdateTwin shall verify the received HTTP status code and if it is not equal to 200 then return NULL ]*/
XinZhangMS 0:f7f1f0d76dd6 541 LogError("Failure sending HTTP request for create device");
XinZhangMS 0:f7f1f0d76dd6 542 BUFFER_delete(responseBuffer);
XinZhangMS 0:f7f1f0d76dd6 543 BUFFER_delete(updateJson);
XinZhangMS 0:f7f1f0d76dd6 544 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 545 }
XinZhangMS 0:f7f1f0d76dd6 546 else
XinZhangMS 0:f7f1f0d76dd6 547 {
XinZhangMS 0:f7f1f0d76dd6 548 /*CodesSRS_IOTHUBDEVICETWIN_12_047: [ Otherwise IoTHubDeviceTwin_UpdateTwin shall save the received updated device twin to the out parameter and return with it ]*/
XinZhangMS 0:f7f1f0d76dd6 549 if (malloc_and_copy_uchar(&result, responseBuffer) != 0)
XinZhangMS 0:f7f1f0d76dd6 550 {
XinZhangMS 0:f7f1f0d76dd6 551 LogError("failed to copy response");
XinZhangMS 0:f7f1f0d76dd6 552 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 553 }
XinZhangMS 0:f7f1f0d76dd6 554 BUFFER_delete(responseBuffer);
XinZhangMS 0:f7f1f0d76dd6 555 BUFFER_delete(updateJson);
XinZhangMS 0:f7f1f0d76dd6 556 }
XinZhangMS 0:f7f1f0d76dd6 557 }
XinZhangMS 0:f7f1f0d76dd6 558 return result;
XinZhangMS 0:f7f1f0d76dd6 559
XinZhangMS 0:f7f1f0d76dd6 560 }
XinZhangMS 0:f7f1f0d76dd6 561
XinZhangMS 0:f7f1f0d76dd6 562 char* IoTHubDeviceTwin_UpdateTwin(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE serviceClientDeviceTwinHandle, const char* deviceId, const char* deviceTwinJson)
XinZhangMS 0:f7f1f0d76dd6 563 {
XinZhangMS 0:f7f1f0d76dd6 564 return IoTHubDeviceTwin_UpdateDeviceOrModuleTwin(serviceClientDeviceTwinHandle, deviceId, NULL, deviceTwinJson);
XinZhangMS 0:f7f1f0d76dd6 565 }
XinZhangMS 0:f7f1f0d76dd6 566
XinZhangMS 0:f7f1f0d76dd6 567 char* IoTHubDeviceTwin_UpdateModuleTwin(IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE serviceClientDeviceTwinHandle, const char* deviceId, const char* moduleId, const char* moduleTwinJson)
XinZhangMS 0:f7f1f0d76dd6 568 {
XinZhangMS 0:f7f1f0d76dd6 569 char* result;
XinZhangMS 0:f7f1f0d76dd6 570 if ((serviceClientDeviceTwinHandle == NULL) || (deviceId == NULL) || (moduleId == NULL) || (moduleTwinJson == NULL))
XinZhangMS 0:f7f1f0d76dd6 571 {
XinZhangMS 0:f7f1f0d76dd6 572 LogError("Input parameter cannot be NULL");
XinZhangMS 0:f7f1f0d76dd6 573 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 574 }
XinZhangMS 0:f7f1f0d76dd6 575 else
XinZhangMS 0:f7f1f0d76dd6 576 {
XinZhangMS 0:f7f1f0d76dd6 577 result = IoTHubDeviceTwin_UpdateDeviceOrModuleTwin(serviceClientDeviceTwinHandle, deviceId, moduleId, moduleTwinJson);
XinZhangMS 0:f7f1f0d76dd6 578 }
XinZhangMS 0:f7f1f0d76dd6 579
XinZhangMS 0:f7f1f0d76dd6 580 return result;
XinZhangMS 0:f7f1f0d76dd6 581 }
XinZhangMS 0:f7f1f0d76dd6 582
XinZhangMS 0:f7f1f0d76dd6 583
XinZhangMS 0:f7f1f0d76dd6 584
XinZhangMS 0:f7f1f0d76dd6 585