Azure IoT / iothub_http_transport

Dependents:   iothub_client_sample_http simplesample_http temp_sensor_anomaly

Files at this revision

API Documentation at this revision

Comitter:
AzureIoTClient
Date:
Tue Sep 22 20:36:43 2015 -0700
Parent:
2:ff9104b866b8
Child:
4:ce756a949fbd
Commit message:
New release

Changed in this revision

iothubtransporthttp.c Show annotated file Show diff for this revision Revisions of this file
iothubtransporthttp.h Show annotated file Show diff for this revision Revisions of this file
--- a/iothubtransporthttp.c	Wed Sep 16 22:42:49 2015 -0700
+++ b/iothubtransporthttp.c	Tue Sep 22 20:36:43 2015 -0700
@@ -28,11 +28,13 @@
 #define APPLICATION_OCTET_STREAM "application/octet-stream"
 #define APPLICATION_VND_MICROSOFT_IOTHUB_JSON "application/vnd.microsoft.iothub.json"
 
-/*DEFAULT_GETMINIMUMPOLLINGTIME is the minimum time in seconds allowed between 2 consecutive GET issues to the service (GET=fetch notifications)*/
+/*DEFAULT_GETMINIMUMPOLLINGTIME is the minimum time in seconds allowed between 2 consecutive GET issues to the service (GET=fetch messages)*/
 /*the default is 25 minutes*/
 #define DEFAULT_GETMINIMUMPOLLINGTIME ((unsigned int)25*60) 
 
 #define MAXIMUM_MESSAGE_SIZE (255*1024-1)
+#define MAXIMUM_PAYLOAD_OVERHEAD 384
+#define MAXIMUM_PROPERTY_OVERHEAD 16
 
 /*forward declaration*/
 static int appendMapToJSON(STRING_HANDLE existing, const char* const* keys, const char* const* values, size_t count);
@@ -49,7 +51,7 @@
     IoTHubTransportHttp_GetSendStatus /* pfIoTHubTransport_GetSendStatus IoTHubTransport_GetSendStatus */
 };
 
-const void* IoTHubTransportHttp_ProvideTransportInterface(void)
+const void* HTTP_Protocol(void)
 {
     return &thisTransportProvider;
 }
@@ -57,14 +59,14 @@
 typedef struct HTTPTRANSPORT_HANDLE_DATA_TAG
 {
     STRING_HANDLE eventHTTPrelativePath;
-    STRING_HANDLE notificationHTTPrelativePath;
+    STRING_HANDLE messageHTTPrelativePath;
     HTTP_HEADERS_HANDLE eventHTTPrequestHeaders;
     STRING_HANDLE hostName;
     HTTPAPIEX_HANDLE httpApiExHandle;
-    HTTP_HEADERS_HANDLE notificationHTTPrequestHeaders;
+    HTTP_HEADERS_HANDLE messageHTTPrequestHeaders;
     STRING_HANDLE abandonHTTPrelativePathBegin;
     HTTPAPIEX_SAS_HANDLE sasObject;
-    bool DoWork_PullNotification;
+    bool DoWork_PullMessage;
     bool doBatchedTransfers;
     bool isFirstPoll;
     unsigned int getMinimumPollingTime;
@@ -108,19 +110,19 @@
     return result;
 }
 
-/*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_034: [Otherwise, IoTHubTransportHttp_Create shall create an immutable string (further called "notification HTTP relative path") from the following pieces: "/devices/" + URL_ENCODED(config->upperConfig->deviceId) + "/messages/devicebound?api-version=2015-08-15-preview".]*/
-static void destroy_notificationHTTPrelativePath(HTTPTRANSPORT_HANDLE_DATA* handleData)
+/*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_034: [Otherwise, IoTHubTransportHttp_Create shall create an immutable string (further called "message HTTP relative path") from the following pieces: "/devices/" + URL_ENCODED(config->upperConfig->deviceId) + "/messages/devicebound?api-version=2015-08-15-preview".]*/
+static void destroy_messageHTTPrelativePath(HTTPTRANSPORT_HANDLE_DATA* handleData)
 {
-    STRING_delete(handleData->notificationHTTPrelativePath);
-    handleData->notificationHTTPrelativePath = NULL;
+    STRING_delete(handleData->messageHTTPrelativePath);
+    handleData->messageHTTPrelativePath = NULL;
 }
 
-/*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_034: [Otherwise, IoTHubTransportHttp_Create shall create an immutable string (further called "notification HTTP relative path") from the following pieces: "/devices/" + URL_ENCODED(config->upperConfig->deviceId) + "/messages/devicebound?api-version=2015-08-15-preview".]*/
-static bool create_notificationHTTPrelativePath(HTTPTRANSPORT_HANDLE_DATA* handleData, const IOTHUBTRANSPORT_CONFIG* config)
+/*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_034: [Otherwise, IoTHubTransportHttp_Create shall create an immutable string (further called "message HTTP relative path") from the following pieces: "/devices/" + URL_ENCODED(config->upperConfig->deviceId) + "/messages/devicebound?api-version=2015-08-15-preview".]*/
+static bool create_messageHTTPrelativePath(HTTPTRANSPORT_HANDLE_DATA* handleData, const IOTHUBTRANSPORT_CONFIG* config)
 {
     bool result;
-    handleData->notificationHTTPrelativePath = STRING_construct("/devices/");
-    if (handleData->notificationHTTPrelativePath == NULL)
+    handleData->messageHTTPrelativePath = STRING_construct("/devices/");
+    if (handleData->messageHTTPrelativePath == NULL)
     {
         result = false;
     }
@@ -129,12 +131,12 @@
         STRING_HANDLE urlEncodedDeviceId = NULL;
         if (!(
             ((urlEncodedDeviceId = URL_EncodeString(config->upperConfig->deviceId)) != NULL) &&
-            (STRING_concat_with_STRING(handleData->notificationHTTPrelativePath, urlEncodedDeviceId) == 0) &&
-            (STRING_concat(handleData->notificationHTTPrelativePath, NOTIFICATION_ENDPOINT_HTTP API_VERSION) == 0)
+            (STRING_concat_with_STRING(handleData->messageHTTPrelativePath, urlEncodedDeviceId) == 0) &&
+            (STRING_concat(handleData->messageHTTPrelativePath, MESSAGE_ENDPOINT_HTTP API_VERSION) == 0)
             ))
         {
             result = false;
-            destroy_notificationHTTPrelativePath(handleData);
+            destroy_messageHTTPrelativePath(handleData);
         }
         else
         {
@@ -272,30 +274,30 @@
     return result;
 }
 
-/*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_059: [Otherwise, IoTHubTransportHttp_Create shall create a set of HTTP headers (further on called "notification HTTP request headers") consisting of the following fixed field names and values:
+/*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_059: [Otherwise, IoTHubTransportHttp_Create shall create a set of HTTP headers (further on called "message HTTP request headers") consisting of the following fixed field names and values:
 "Authorization": " "]*/
-static void destroy_notificationHTTPrequestHeaders(HTTPTRANSPORT_HANDLE_DATA* handleData)
+static void destroy_messageHTTPrequestHeaders(HTTPTRANSPORT_HANDLE_DATA* handleData)
 {
-    HTTPHeaders_Free(handleData->notificationHTTPrequestHeaders);
-    handleData->notificationHTTPrequestHeaders = NULL;
+    HTTPHeaders_Free(handleData->messageHTTPrequestHeaders);
+    handleData->messageHTTPrequestHeaders = NULL;
 }
 
-/*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_059: [Otherwise, IoTHubTransportHttp_Create shall create a set of HTTP headers (further on called "notification HTTP request headers") consisting of the following fixed field names and values:
+/*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_059: [Otherwise, IoTHubTransportHttp_Create shall create a set of HTTP headers (further on called "message HTTP request headers") consisting of the following fixed field names and values:
 "Authorization": " "]*/
-static bool create_notificationHTTPrequestHeaders(HTTPTRANSPORT_HANDLE_DATA* handleData, const IOTHUBTRANSPORT_CONFIG* config)
+static bool create_messageHTTPrequestHeaders(HTTPTRANSPORT_HANDLE_DATA* handleData, const IOTHUBTRANSPORT_CONFIG* config)
 {
     bool result;
     (void)config;
-    handleData->notificationHTTPrequestHeaders = HTTPHeaders_Alloc();
-    if (handleData->notificationHTTPrequestHeaders == NULL)
+    handleData->messageHTTPrequestHeaders = HTTPHeaders_Alloc();
+    if (handleData->messageHTTPrequestHeaders == NULL)
     {
         result = false;
     }
     else
     {
-        if (HTTPHeaders_AddHeaderNameValuePair(handleData->notificationHTTPrequestHeaders, "Authorization", " ") != HTTP_HEADERS_OK)
+        if (HTTPHeaders_AddHeaderNameValuePair(handleData->messageHTTPrequestHeaders, "Authorization", " ") != HTTP_HEADERS_OK)
         {
-            destroy_notificationHTTPrequestHeaders(handleData);
+            destroy_messageHTTPrequestHeaders(handleData);
             result = false;
         }
         else
@@ -328,7 +330,7 @@
         if (!(
             ((urlEncodedDeviceId = URL_EncodeString(config->upperConfig->deviceId)) != NULL) &&
             (STRING_concat_with_STRING(handleData->abandonHTTPrelativePathBegin, urlEncodedDeviceId) == 0) &&
-            (STRING_concat(handleData->abandonHTTPrelativePathBegin, NOTIFICATION_ENDPOINT_HTTP_ETAG) == 0)
+            (STRING_concat(handleData->abandonHTTPrelativePathBegin, MESSAGE_ENDPOINT_HTTP_ETAG) == 0)
             ))
         {
             LogError("unable to STRING_concat\r\n");
@@ -472,18 +474,18 @@
         else
         {
             bool was_eventHTTPrelativePath_ok = create_eventHTTPrelativePath(result, config);
-            bool was_notificationHTTPrelativePath_ok = was_eventHTTPrelativePath_ok && create_notificationHTTPrelativePath(result, config);
-            bool was_eventHTTPrequestHeaders_ok = was_notificationHTTPrelativePath_ok && create_eventHTTPrequestHeaders(result, config);
+            bool was_messageHTTPrelativePath_ok = was_eventHTTPrelativePath_ok && create_messageHTTPrelativePath(result, config);
+            bool was_eventHTTPrequestHeaders_ok = was_messageHTTPrelativePath_ok && create_eventHTTPrequestHeaders(result, config);
             bool was_hostName_ok = was_eventHTTPrequestHeaders_ok && create_hostName(result, config);
             bool was_httpApiExHandle_ok = was_hostName_ok && create_httpApiExHandle(result, config);
-            bool was_notificationHTTPrequestHeaders_ok = was_httpApiExHandle_ok && create_notificationHTTPrequestHeaders(result, config);
-            bool was_abandonHTTPrelativePathBegin_ok = was_notificationHTTPrequestHeaders_ok && create_abandonHTTPrelativePathBegin(result, config);
+            bool was_messageHTTPrequestHeaders_ok = was_httpApiExHandle_ok && create_messageHTTPrequestHeaders(result, config);
+            bool was_abandonHTTPrelativePathBegin_ok = was_messageHTTPrequestHeaders_ok && create_abandonHTTPrelativePathBegin(result, config);
             bool was_sasObject_ok = was_abandonHTTPrelativePathBegin_ok && create_deviceSASObject(result, config);
 
-            /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_011: [Otherwise, IoTHubTransportHttp_Create shall set a flag called "DoWork_PullNotification" to false, succeed and return a non-NULL value.]*/
+            /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_011: [Otherwise, IoTHubTransportHttp_Create shall set a flag called "DoWork_PullMessage" to false, succeed and return a non-NULL value.]*/
             if (was_sasObject_ok)
             {
-                result->DoWork_PullNotification = false;
+                result->DoWork_PullMessage = false;
                 result->doBatchedTransfers = false;
                 result->isFirstPoll = true;
                 result->getMinimumPollingTime = DEFAULT_GETMINIMUMPOLLINGTIME;
@@ -494,16 +496,16 @@
             {
                 /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_004: [If creating the string fail for any reason then IoTHubTransportHttp_Create shall fail and return NULL.] */
                 if (was_eventHTTPrelativePath_ok) destroy_eventHTTPrelativePath(result);
-                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_035: [If creating the notification HTTP relative path fails, then IoTHubTransportHttp_Create shall fail and return NULL.] */
-                if (was_notificationHTTPrelativePath_ok) destroy_notificationHTTPrelativePath(result);
+                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_035: [If creating the message HTTP relative path fails, then IoTHubTransportHttp_Create shall fail and return NULL.] */
+                if (was_messageHTTPrelativePath_ok) destroy_messageHTTPrelativePath(result);
                 /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_006: [If creating the event HTTP request headers fails, then IoTHubTransportHttp_Create shall fail and return NULL.] */
                 if (was_eventHTTPrequestHeaders_ok) destroy_eventHTTPrequestHeaders(result);
                 /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_008: [If creating the hostname fails then IoTHubTransportHttp_Create shall fail and return NULL.] */
                 if (was_hostName_ok) destroy_hostName(result);
                 /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_010: [If creating the HTTPAPIEX_HANDLE fails then IoTHubTransportHttp_Create shall fail and return NULL.] */
                 if (was_httpApiExHandle_ok) destroy_httpApiExHandle(result);
-                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_060: [If creating notification HTTP request headers then IoTHubTransportHttp_Create shall fail and return NULL.]*/
-                if (was_notificationHTTPrequestHeaders_ok) destroy_notificationHTTPrequestHeaders(result);
+                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_060: [If creating message HTTP request headers then IoTHubTransportHttp_Create shall fail and return NULL.]*/
+                if (was_messageHTTPrequestHeaders_ok) destroy_messageHTTPrequestHeaders(result);
                 /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_062: [If creating the abandonHTTPrelativePathBegin fails then IoTHubTransportHttp_Create shall fail and return NULL] */
                 if (was_abandonHTTPrelativePathBegin_ok) destroy_abandonHTTPrelativePathBegin(result);
 
@@ -522,11 +524,11 @@
     {
         /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_013: [Otherwise IoTHubTransportHttp_Destroy shall free all the resources currently in use.] */
         destroy_eventHTTPrelativePath(handle);
-        destroy_notificationHTTPrelativePath(handle);
+        destroy_messageHTTPrelativePath(handle);
         destroy_eventHTTPrequestHeaders(handle);
         destroy_hostName(handle);
         destroy_httpApiExHandle(handle);
-        destroy_notificationHTTPrequestHeaders(handle);
+        destroy_messageHTTPrequestHeaders(handle);
         destroy_abandonHTTPrelativePathBegin(handle);
         destroy_SASObject(handle);
         free(handle);
@@ -544,9 +546,9 @@
     }
     else
     {
-        /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_056: [Otherwise, IoTHubTransportHttp_Subscribe shall set the flag called DoWork_PullNotifications to true and succeed.] */
+        /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_056: [Otherwise, IoTHubTransportHttp_Subscribe shall set the flag called DoWork_PullMessages to true and succeed.] */
         HTTPTRANSPORT_HANDLE_DATA* handleData = (HTTPTRANSPORT_HANDLE_DATA*)handle;
-        handleData->DoWork_PullNotification = true;
+        handleData->DoWork_PullMessage = true;
         result = 0;
     }
     return result;
@@ -558,14 +560,14 @@
     if (handle != NULL)
     {
         HTTPTRANSPORT_HANDLE_DATA* handleData = (HTTPTRANSPORT_HANDLE_DATA*)handle;
-        /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_058: [Otherwise it shall set the flag DoWork_PullNotification to false.] */
-        handleData->DoWork_PullNotification = false;
+        /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_058: [Otherwise it shall set the flag DoWork_PullMessage to false.] */
+        handleData->DoWork_PullMessage = false;
     }
 }
 
 /*produces a representation of the properties, if they exist*/
 /*if they do not exist, produces ""*/
-static int concat_Properties(STRING_HANDLE existing, MAP_HANDLE map)
+static int concat_Properties(STRING_HANDLE existing, MAP_HANDLE map, size_t* propertiesMessageSizeContribution)
 {
     int result;
     const char*const* keys;
@@ -584,6 +586,7 @@
             /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_076: [If IoTHubMessage does not have properties, then "properties":{...} shall be missing from the payload*/
             /*no properties - do nothing with existing*/
             result = 0;
+            *propertiesMessageSizeContribution = 0;
         }
         else
         {
@@ -602,6 +605,13 @@
             else
             {
                 /*all is fine*/
+                size_t i;
+                *propertiesMessageSizeContribution = 0;
+                for (i = 0;i < count;i++)
+                {
+                    /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_120: [Every property name shall add to the message size the length of the property name + the length of the property value + 16 bytes.] */
+                    *propertiesMessageSizeContribution += (strlen(keys[i]) + strlen(values[i]) + MAXIMUM_PROPERTY_OVERHEAD);
+                }
                 result = 0;
             }
         }
@@ -658,11 +668,12 @@
 
 /*makes the following string:{"body":"base64 encoding of the message content"[,"properties":{"a":"valueOfA"}]}*/
 /*return NULL if there was a failure, or a non-NULL STRING_HANDLE that contains the intended data*/
-static STRING_HANDLE make1EventJSONitem(PDLIST_ENTRY item)
+static STRING_HANDLE make1EventJSONitem(PDLIST_ENTRY item, size_t *messageSizeContribution)
 {
     STRING_HANDLE result; /*temp wants to contain :{"body":"base64 encoding of the message content"[,"properties":{"a":"valueOfA"}]}*/
     IOTHUB_MESSAGE_LIST* message = containingRecord(item, IOTHUB_MESSAGE_LIST, entry);
     IOTHUBMESSAGE_CONTENT_TYPE contentType = IoTHubMessage_GetContentType(message->messageHandle);
+    
     switch (contentType)
     {
     case IOTHUBMESSAGE_BYTEARRAY:
@@ -694,10 +705,11 @@
                 }
                 else
                 {
+                    size_t propertiesSize;
                     if (!(
                         (STRING_concat_with_STRING(result, encoded) == 0) &&
                         (STRING_concat(result, "\"") == 0) && /*\" because closing value*/
-                        (concat_Properties(result, IoTHubMessage_Properties(message->messageHandle)) == 0) &&
+                        (concat_Properties(result, IoTHubMessage_Properties(message->messageHandle), &propertiesSize) == 0) &&
                         (STRING_concat(result, "},") == 0) /*the last comma shall be replaced by a ']' by DaCr's suggestion (which is awesome enough to receive credits in the source code)*/
                         ))
                     {
@@ -708,6 +720,8 @@
                     else
                     {
                         /*all is fine... */
+                        /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_119: [The message size is computed from the length of the payload + 384.] */
+                        *messageSizeContribution = size + MAXIMUM_PAYLOAD_OVERHEAD + propertiesSize;
                     }
                     STRING_delete(encoded);
                 }
@@ -743,10 +757,11 @@
                 }
                 else
                 {
+                    size_t propertiesSize;
                     if (!(
                         (STRING_concat_with_STRING(result, asJson) == 0) &&
                         (STRING_concat(result, ",\"base64Encoded\":false") == 0) &&
-                        (concat_Properties(result, IoTHubMessage_Properties(message->messageHandle)) == 0) &&
+                        (concat_Properties(result, IoTHubMessage_Properties(message->messageHandle), &propertiesSize) == 0) &&
                         (STRING_concat(result, "},") == 0) /*the last comma shall be replaced by a ']' by DaCr's suggestion (which is awesome enough to receive credits in the source code)*/
                         ))
                     {
@@ -757,6 +772,8 @@
                     else
                     {
                         /*result has the intended content*/
+                        /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_119: [The message size is computed from the length of the payload + 384.] */
+                        *messageSizeContribution = strlen(source) + MAXIMUM_PAYLOAD_OVERHEAD + propertiesSize;
                     }
                     STRING_delete(asJson);
                 }
@@ -787,7 +804,7 @@
 static MAKE_PAYLOAD_RESULT makePayload(HTTPTRANSPORT_HANDLE_DATA* handleData, STRING_HANDLE* payload)
 {
     MAKE_PAYLOAD_RESULT result;
-    
+    size_t allMessagesSize = 0;
     *payload = STRING_construct("[");
     if (*payload == NULL)
     {
@@ -803,7 +820,8 @@
         bool keepGoing = true; /*keepGoing gets sometimes to false from within the loop*/
         while (keepGoing && ((actual = handleData->waitingToSend->Flink) != handleData->waitingToSend))
         {
-            STRING_HANDLE temp = make1EventJSONitem(actual);
+            size_t messageSize;
+            STRING_HANDLE temp = make1EventJSONitem(actual, &messageSize);
             if (isFirst)
             {
                 isFirst = false;
@@ -818,7 +836,8 @@
                 else
                 {
                     /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_071: [If the oldest message in waitingToSend causes the message size to exceed the message size limit then it shall be removed from waitingToSend, and IoTHubClient_LL_SendComplete shall be called. Parameter PDLIST_ENTRY completed shall point to a list containing only the oldest item, and parameter IOTHUB_BATCHSTATE result shall be set to IOTHUB_BATCHSTATE_FAILED.]*/
-                    if (STRING_length(temp) >= MAXIMUM_MESSAGE_SIZE)
+                    /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_118: [The message size shall be limited to 255KB - 1 byte.]*/
+                    if (messageSize > MAXIMUM_MESSAGE_SIZE)
                     {
                         PDLIST_ENTRY head = DList_RemoveHeadList(handleData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
                         DList_InsertTailList(&(handleData->eventConfirmations), head);
@@ -842,6 +861,7 @@
                             /*first item was put nicely in the payload*/
                             PDLIST_ENTRY head = DList_RemoveHeadList(handleData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
                             DList_InsertTailList(&(handleData->eventConfirmations), head);
+                            allMessagesSize += messageSize;
                         }
                     }
                     STRING_delete(temp);
@@ -859,7 +879,7 @@
                 }
                 else
                 {
-                    if (STRING_length(*payload) + STRING_length(temp) > MAXIMUM_MESSAGE_SIZE)
+                    if (allMessagesSize + messageSize > MAXIMUM_MESSAGE_SIZE)
                     {
                         /*this item doesn't make it to the payload, but the payload is valid so far*/
                         /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_072: [If at any point during construction of the string there are errors, IoTHubTransportHttp_DoWork shall use the so far constructed string as payload.]*/
@@ -878,6 +898,7 @@
                         /*cool, the payload made it there, let's continue... */
                         PDLIST_ENTRY head = DList_RemoveHeadList(handleData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
                         DList_InsertTailList(&(handleData->eventConfirmations), head);
+                        allMessagesSize += messageSize;
                     }
                     STRING_delete(temp);
                 }
@@ -1017,16 +1038,22 @@
         }
         else
         {
-            const unsigned char* messageContent;
-            size_t messageSize;
+            const unsigned char* messageContent=NULL;
+            size_t messageSize=0;
+            size_t originalMessageSize=0;
             IOTHUB_MESSAGE_LIST* message = containingRecord(handleData->waitingToSend->Flink, IOTHUB_MESSAGE_LIST, entry);
             IOTHUBMESSAGE_CONTENT_TYPE contentType = IoTHubMessage_GetContentType(message->messageHandle);
 
+            /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_122: [The message size is computed from the length of the payload + 384.]*/
             if (!(
-                ((contentType == IOTHUBMESSAGE_BYTEARRAY) && (IoTHubMessage_GetByteArray(message->messageHandle, &messageContent, &messageSize)==IOTHUB_MESSAGE_OK)) ||
+                (((contentType == IOTHUBMESSAGE_BYTEARRAY) && 
+                    (IoTHubMessage_GetByteArray(message->messageHandle, &messageContent, &originalMessageSize)==IOTHUB_MESSAGE_OK)) ? (messageSize= originalMessageSize + MAXIMUM_PAYLOAD_OVERHEAD, 1): 0)
+                
+                ||
+
                 ((contentType == IOTHUBMESSAGE_STRING) && (
                     messageContent = (const unsigned char*)IoTHubMessage_GetString(message->messageHandle), 
-                    (messageSize = (messageContent == NULL)?0:strlen((const char*)messageContent)), 
+                    (messageSize = MAXIMUM_PAYLOAD_OVERHEAD + (originalMessageSize = ((messageContent == NULL)?0:strlen((const char*)messageContent)))), 
                     messageContent!=NULL)
                     )
                 ))
@@ -1037,7 +1064,8 @@
             else
             {
                 /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_109: [If the oldest message in waitingToSend causes the message to exceed the message size limit then it shall be removed from waitingToSend, and IoTHubClient_LL_SendComplete shall be called. Parameter PDLIST_ENTRY completed shall point to a list containing only the oldest item, and parameter IOTHUB_BATCHSTATE result shall be set to IOTHUB_BATCHSTATE_FAILED.]*/
-                if (messageSize >= MAXIMUM_MESSAGE_SIZE)
+                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_121: [The message size shall be limited to 255KB -1 bytes.] */
+                if (messageSize > MAXIMUM_MESSAGE_SIZE)
                 {
                     PDLIST_ENTRY head = DList_RemoveHeadList(handleData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
                     DList_InsertTailList(&(handleData->eventConfirmations), head);
@@ -1079,32 +1107,44 @@
                                 bool goOn = true;
                                 for (i = 0; (i < count) && goOn; i++)
                                 {
-                                    
-                                    STRING_HANDLE temp = STRING_construct(IOTHUB_APP_PREFIX);
-                                    if (temp == NULL)
+                                    /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_123: [Every property name shall add  to the message size the length of the property name + the length of the property value + 16 bytes.] */
+                                    messageSize += (strlen(values[i]) + strlen(keys[i]) + MAXIMUM_PROPERTY_OVERHEAD);
+                                    if (messageSize > MAXIMUM_MESSAGE_SIZE)
                                     {
-                                        /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_108: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
-                                        LogError("unable to STRING_construct\r\n");
+                                        /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_121: [The message size shall be limited to 255KB -1 bytes.] */
+                                        PDLIST_ENTRY head = DList_RemoveHeadList(handleData->waitingToSend); /*actually this is the same as "actual", but now it is removed*/
+                                        DList_InsertTailList(&(handleData->eventConfirmations), head);
+                                        IoTHubClient_LL_SendComplete(iotHubClientHandle, &(handleData->eventConfirmations), IOTHUB_BATCHSTATE_FAILED); /*takes care of emptying the list too*/
                                         goOn = false;
                                     }
                                     else
                                     {
-                                        if (STRING_concat(temp, keys[i]) != 0)
+                                        STRING_HANDLE temp = STRING_construct(IOTHUB_APP_PREFIX);
+                                        if (temp == NULL)
                                         {
                                             /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_108: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
-                                            LogError("unable to STRING_concat\r\n");
+                                            LogError("unable to STRING_construct\r\n");
                                             goOn = false;
                                         }
                                         else
                                         {
-                                            if (HTTPHeaders_ReplaceHeaderNameValuePair(clonedEventHTTPrequestHeaders, STRING_c_str(temp), values[i]) != HTTP_HEADERS_OK)
+                                            if (STRING_concat(temp, keys[i]) != 0)
                                             {
                                                 /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_108: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
-                                                LogError("unable to HTTPHeaders_ReplaceHeaderNameValuePair\r\n");
+                                                LogError("unable to STRING_concat\r\n");
                                                 goOn = false;
                                             }
+                                            else
+                                            {
+                                                if (HTTPHeaders_ReplaceHeaderNameValuePair(clonedEventHTTPrequestHeaders, STRING_c_str(temp), values[i]) != HTTP_HEADERS_OK)
+                                                {
+                                                    /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_108: [If any HTTP header operation fails, _DoWork shall advance to the next action.] */
+                                                    LogError("unable to HTTPHeaders_ReplaceHeaderNameValuePair\r\n");
+                                                    goOn = false;
+                                                }
+                                            }
+                                            STRING_delete(temp);
                                         }
-                                        STRING_delete(temp); 
                                     }
                                 }
 
@@ -1122,7 +1162,7 @@
                                     }
                                     else
                                     {
-                                        if (BUFFER_build(toBeSend, messageContent, messageSize) != 0)
+                                        if (BUFFER_build(toBeSend, messageContent, originalMessageSize) != 0)
                                         {
                                             LogError("unable to BUFFER_build\r\n");
                                         }
@@ -1311,11 +1351,11 @@
     }
 }
 
-static void DoNotifications(TRANSPORT_HANDLE handle, IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle)
+static void DoMessages(TRANSPORT_HANDLE handle, IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle)
 {
     HTTPTRANSPORT_HANDLE_DATA* handleData = (HTTPTRANSPORT_HANDLE_DATA*)handle;
-    /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_057: [If flag DoWork_PullNotification is set to false then _DoWork shall advance to the next action.] */
-    if (handleData->DoWork_PullNotification)
+    /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_057: [If flag DoWork_PullMessage is set to false then _DoWork shall advance to the next action.] */
+    if (handleData->DoWork_PullMessage)
     {
         /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_116: [After client creation, the first GET shall be allowed no matter what the value of GetMinimumPollingTime.] */
         /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_117: [If time is not available then all calls shall be treated as if they are the first one.] */
@@ -1343,8 +1383,8 @@
                 unsigned int statusCode;
                 /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_036: [Otherwise, IoTHubTransportHttp_DoWork shall call HTTPAPIEX_SAS_ExecuteRequest passing the following parameters
 requestType: GET
-relativePath: the notification HTTP relative path
-requestHttpHeadersHandle: notification HTTP request headers created by _Create
+relativePath: the message HTTP relative path
+requestHttpHeadersHandle: message HTTP request headers created by _Create
 requestContent: NULL
 statusCode: a pointer to unsigned int which shall be later examined
 responseHeadearsHandle: a new instance of HTTP headers
@@ -1354,8 +1394,8 @@
                     handleData->sasObject,
                     handleData->httpApiExHandle,     
                     HTTPAPI_REQUEST_GET,                                            /*requestType: GET*/
-                    STRING_c_str(handleData->notificationHTTPrelativePath),         /*relativePath: the notification HTTP relative path*/
-                    handleData->notificationHTTPrequestHeaders,                     /*requestHttpHeadersHandle: notification HTTP request headers created by _Create*/
+                    STRING_c_str(handleData->messageHTTPrelativePath),         /*relativePath: the message HTTP relative path*/
+                    handleData->messageHTTPrequestHeaders,                     /*requestHttpHeadersHandle: message HTTP request headers created by _Create*/
                     NULL,                                                           /*requestContent: NULL*/
                     &statusCode,                                                    /*statusCode: a pointer to unsigned int which shall be later examined*/
                     responseHTTPHeaders,                                            /*responseHeadearsHandle: a new instance of HTTP headers*/
@@ -1464,21 +1504,21 @@
                                         }
                                         else
                                         {
-                                            /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_043: [Otherwise, _DoWork shall call IoTHubClient_LL_NotificationCallback with parameters handle = iotHubClientHandle and notificationMessage = newly created message.]*/
-                                            IOTHUBMESSAGE_DISPOSITION_RESULT notificationResult = IoTHubClient_LL_NotificationCallback(iotHubClientHandle, receivedMessage);
-                                            if (notificationResult == IOTHUBMESSAGE_ACCEPTED)
+                                            /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_043: [Otherwise, _DoWork shall call IoTHubClient_LL_MessageCallback with parameters handle = iotHubClientHandle and message = newly created message.]*/
+                                            IOTHUBMESSAGE_DISPOSITION_RESULT messageResult = IoTHubClient_LL_MessageCallback(iotHubClientHandle, receivedMessage);
+                                            if (messageResult == IOTHUBMESSAGE_ACCEPTED)
                                             {
-                                                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_044: [If IoTHubClient_LL_NotificationCallback returns IOTHUBMESSAGE_ACCEPTED then _DoWork shall "accept" the message.]*/
+                                                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_044: [If IoTHubClient_LL_MessageCallback returns IOTHUBMESSAGE_ACCEPTED then _DoWork shall "accept" the message.]*/
                                                 abandonOrAcceptMessage(handle, etagValue, ACCEPT);
                                             }
-                                            else if (notificationResult == IOTHUBMESSAGE_REJECTED)
+                                            else if (messageResult == IOTHUBMESSAGE_REJECTED)
                                             {
-                                                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_074: [If IoTHubClient_LL_NotificationCallback returns IOTHUBMESSAGE_REJECTED then _DoWork shall "reject" the message.]*/
+                                                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_074: [If IoTHubClient_LL_MessageCallback returns IOTHUBMESSAGE_REJECTED then _DoWork shall "reject" the message.]*/
                                                 abandonOrAcceptMessage(handle, etagValue, REJECT);
                                             }
                                             else
                                             {
-                                                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_079: [If IoTHubClient_LL_NotificationCallback returns IOTHUBMESSAGE_ABANDONED then _DoWork shall "abandon" the message.] */
+                                                /*Codes_SRS_IOTHUBTRANSPORTTHTTP_02_079: [If IoTHubClient_LL_MessageCallback returns IOTHUBMESSAGE_ABANDONED then _DoWork shall "abandon" the message.] */
                                                 abandonOrAcceptMessage(handle, etagValue, ABANDON);
                                             }
                                         }
@@ -1509,7 +1549,7 @@
     if ((handle != NULL) && (iotHubClientHandle != NULL))
     {
         DoEvent(handle, iotHubClientHandle);
-        DoNotifications(handle, iotHubClientHandle);
+        DoMessages(handle, iotHubClientHandle);
     }
 }
 
--- a/iothubtransporthttp.h	Wed Sep 16 22:42:49 2015 -0700
+++ b/iothubtransporthttp.h	Tue Sep 22 20:36:43 2015 -0700
@@ -19,9 +19,9 @@
 
     extern void IoTHubTransportHttp_DoWork(TRANSPORT_HANDLE handle, IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle);
 
-	extern IOTHUB_CLIENT_RESULT IoTHubTransportHttp_GetSendStatus(TRANSPORT_HANDLE handle, IOTHUB_CLIENT_STATUS *iotHubClientStatus);
+    extern IOTHUB_CLIENT_RESULT IoTHubTransportHttp_GetSendStatus(TRANSPORT_HANDLE handle, IOTHUB_CLIENT_STATUS *iotHubClientStatus);
     extern IOTHUB_CLIENT_RESULT IoTHubTransportHttp_SetOption(TRANSPORT_HANDLE handle, const char* optionName, const void* value);
-    extern const void* IoTHubTransportHttp_ProvideTransportInterface(void);
+    extern const void* HTTP_Protocol(void);
 
 #ifdef __cplusplus
 }