Skip to content

Commit

Permalink
Add Device Streaming to Azure IoT C SDK
Browse files Browse the repository at this point in the history
Enable Device Streaming E2E tests

Revert improvements in initialize_iothub_client (iothub_client_core_ll.c)

Update CONSTBUFFER function calls in iothubtransport_amqp_streaming_ut

Fixes for device streaming code and tests

Fix memory leak on device streaming e2e tests

Update device streaming code with macro_utils renamed macros

Adding timeouts to device streaming e2e test requests

Disable device streaming over websockets tests if using wolfssl

Set trusted cert on uws_client to connect to streaming gateway (ds e2e tests)

Disable device streaming tests over websockets when using wolfssl

Add more logging on device streaming e2e tests (print SGW urls)

Update device streaming code to use product info callback

Change device streaming proxy sample to chunk outgoing data into up to 64kb WS frames

update readme with device streams

DEVICE_STREAM_C2D_REQUEST shall be const (GH issue Azure#901)

Rename iothub_client_streaming.h (gh Azure#900)

Fixes for DeviceStreaming samples (includes gh#820)

Fixed incorrect includes
  • Loading branch information
ewertons authored and Emil-Juhl committed Jul 2, 2020
1 parent c8b6a10 commit 5a46693
Show file tree
Hide file tree
Showing 115 changed files with 18,462 additions and 72 deletions.
8 changes: 5 additions & 3 deletions iothub_client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ set(iothub_client_c_files
./src/iothub_client_core_ll.c
./src/iothub_client_diagnostic.c
./src/iothub_client_ll.c
./src/iothub_client_streaming.c
./src/iothub_device_client.c
./src/iothub_device_client_ll.c
./src/iothub_message.c
Expand All @@ -40,6 +41,7 @@ set(iothub_client_h_files
./inc/iothub_client_version.h
./inc/iothub_device_client.h
./inc/iothub_device_client_ll.h
./inc/iothub_client_streaming.h
./inc/iothub_module_client.h
./inc/iothub_module_client_ll.h
./inc/iothub_transport_ll.h
Expand Down Expand Up @@ -134,6 +136,7 @@ if(${use_amqp})
./src/iothubtransport_amqp_telemetry_messenger.c
./src/iothubtransport_amqp_twin_messenger.c
./src/iothubtransport_amqp_messenger.c
./src/iothubtransport_amqp_streaming.c
./src/iothubtransportamqp_methods.c
./src/message_queue.c
./src/uamqp_messaging.c
Expand All @@ -150,6 +153,7 @@ if(${use_amqp})
./inc/internal/iothubtransport_amqp_telemetry_messenger.h
./inc/internal/iothubtransport_amqp_twin_messenger.h
./inc/internal/iothubtransport_amqp_messenger.h
./inc/internal/iothubtransport_amqp_streaming.h
./inc/internal/iothubtransportamqp_methods.h
./inc/internal/message_queue.h
./inc/internal/uamqp_messaging.h
Expand Down Expand Up @@ -388,9 +392,7 @@ if (${build_as_dynamic})
set(iothub_def_file ${iothub_def_file} ./src/upload_to_blob.def)
endif()

if(use_amqp)
set(iothub_def_file ${iothub_def_file} ./src/iothub_transport_amqp.def)
endif()
set(iothub_def_file ${iothub_def_file} ./src/iothub_transport_amqp.def)

if(use_http)
set(iothub_def_file ${iothub_def_file} ./src/iothub_transport_http.def)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# iothub_client_streaming Requirements


## Overview

This module provides functionality for handling Device Stream requests and responses.


## Exposed API

```c
typedef struct DEVICE_STREAM_C2D_REQUEST_TAG
{
char* name;
char* uri;
char* authorization_token;
char* request_id;
} DEVICE_STREAM_C2D_REQUEST;

typedef struct DEVICE_STREAM_C2D_RESPONSE_TAG
{
bool accept;
char* request_id;
} DEVICE_STREAM_C2D_RESPONSE;

typedef DEVICE_STREAM_C2D_RESPONSE* (*DEVICE_STREAM_C2D_REQUEST_CALLBACK)(DEVICE_STREAM_C2D_REQUEST* request, const void* context);

extern DEVICE_STREAM_C2D_RESPONSE* IoTHubClient_StreamC2DResponseCreate(DEVICE_STREAM_C2D_REQUEST* request, bool accept, char* data, char* content_type, char* content_encoding);
extern DEVICE_STREAM_C2D_REQUEST* IoTHubClient_StreamC2DRequestClone(DEVICE_STREAM_C2D_REQUEST* request);
extern void IoTHubClient_StreamC2DResponseDestroy(DEVICE_STREAM_C2D_RESPONSE* response);
extern void IoTHubClient_StreamC2DRequestDestroy(DEVICE_STREAM_C2D_REQUEST* request);
```
### IoTHubClient_StreamC2DResponseCreate
```c
extern DEVICE_STREAM_C2D_RESPONSE* IoTHubClient_StreamC2DResponseCreate(DEVICE_STREAM_C2D_REQUEST* request, bool accept, char* data, char* content_type, char* content_encoding);
```

**SRS_IOTHUB_CLIENT_STREAMING_09_010: [** If `request` is NULL, the function shall return NULL **]**

**SRS_IOTHUB_CLIENT_STREAMING_09_011: [** The function shall allocate memory for a new instance of DEVICE_STREAM_C2D_RESPONSE (aka `response`) **]**

**SRS_IOTHUB_CLIENT_STREAMING_09_012: [** If malloc fails, the function shall return NULL **]**

**SRS_IOTHUB_CLIENT_STREAMING_09_013: [** `request->request_id` shall be copied into `response->request_id` **]**


### IoTHubClient_StreamC2DRequestClone

```c
extern DEVICE_STREAM_C2D_REQUEST* IoTHubClient_StreamC2DRequestClone(DEVICE_STREAM_C2D_REQUEST* request);
```
**SRS_IOTHUB_CLIENT_STREAMING_09_016: [** If `request` is NULL, the function shall return NULL **]**
**SRS_IOTHUB_CLIENT_STREAMING_09_017: [** The function shall allocate memory for a new instance of DEVICE_STREAM_C2D_REQUEST (aka `clone`) **]**
**SRS_IOTHUB_CLIENT_STREAMING_09_018: [** If malloc fails, the function shall return NULL **]**
**SRS_IOTHUB_CLIENT_STREAMING_09_019: [** All fields of `request` shall be copied into `clone` **]**
**SRS_IOTHUB_CLIENT_STREAMING_09_020: [** If any field fails to be copied, the function shall release the memory allocated and return NULL **]**
### IoTHubClient_StreamC2DResponseDestroy
```c
extern void IoTHubClient_StreamC2DResponseDestroy(DEVICE_STREAM_C2D_RESPONSE* response);
```

**SRS_IOTHUB_CLIENT_STREAMING_09_021: [** If `request` is NULL, the function shall return **]**

**SRS_IOTHUB_CLIENT_STREAMING_09_022: [** The memory allocated for `response` shall be released **]**


### IoTHubClient_StreamC2DRequestDestroy

```c
extern void IoTHubClient_StreamC2DRequestDestroy(DEVICE_STREAM_C2D_REQUEST* request);
```
**SRS_IOTHUB_CLIENT_STREAMING_09_023: [** If `request` is NULL, the function shall return **]**
**SRS_IOTHUB_CLIENT_STREAMING_09_024: [** The memory allocated for `request` shall be released **]**
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ extern IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_GetDeviceTwinAsync(IOTHUB_CLIENT
extern IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetDeviceMethodCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback);
extern IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetDeviceMethodCallback_Ex(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inboundDeviceMethodCallback, void* userContextCallback);
extern IOTHUB_CLIENT_RESULT IoTHubClient_LL_DeviceMethodResponse(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, uint32_t methodId, unsigned char* response, size_t responeSize);

## Device Stream
extern IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetStreamRequestCallback(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, DEVICE_STREAM_C2D_REQUEST_CALLBACK streamRequestCallback, const void* context);
extern IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SendStreamResponse(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, DEVICE_STREAM_C2D_RESPONSE* response);
```
## IoTHubClient_LL_CreateFromConnectionString
Expand Down Expand Up @@ -204,6 +208,7 @@ extern IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_Create(const IOTHUB_CLIENT_CONFIG
**SRS_IOTHUBCLIENT_LL_07_029: [** `IoTHubClient_LL_Create` shall create the Auth module with the device_key, device_id, deviceSasToken, and/or module_id values **]**
## IoTHubClient_LL_CreateWithTransport
```c
Expand Down Expand Up @@ -232,10 +237,12 @@ extern IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateWithTransport(IOTHUB_CLIEN

**SRS_IOTHUBCLIENT_LL_17_006: [** `IoTHubClient_LL_CreateWithTransport` shall call the transport _Register function with the `IOTHUB_DEVICE_CONFIG` populated structure and waitingToSend list. **]**

**SRS_IOTHUBCLIENT_LL_17_007: [** If the _Register function fails, this function shall fail and return `NULL`. **]**
**SRS_IOTHUBCLIENT_LL_17_007: [** If the _Register function fails, this function shall fail and return `NULL`. **]** **SRS_IOTHUBCLIENT_LL_17_007: [** If the _Register function fails, this function shall fail and return `NULL`. **]**

**SRS_IOTHUBCLIENT_LL_25_125: [** `IoTHubClient_LL_CreateWithTransport` shall set the default retry policy as Exponential backoff with jitter and if succeed and return a `non-NULL` handle. **]**



## IoTHubClient_LL_Destroy

```c
Expand Down Expand Up @@ -309,6 +316,8 @@ extern void IoTHubClient_LL_DoWork(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle);

**SRS_IOTHUBCLIENT_LL_07_012: [** If 'IoTHubTransport_ProcessItem' returns any other value `IoTHubClient_LL_DoWork` shall destroy the `IOTHUB_QUEUE_DATA_ITEM` item. **]**



## IoTHubClient_LL_SendComplete

```c
Expand Down Expand Up @@ -984,3 +993,31 @@ This function uses the same logic as `IoTHubClient_LL_SetInputMessageCallback` b
**SRS_IOTHUBCLIENT_LL_31_141: [** `IoTHubClient_LL_SetInputMessageCallbackEx` shall copy the data passed in extended context. **]**
## IoTHubClientCore_LL_SetStreamRequestCallback
```c
extern IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SetStreamRequestCallback(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, DEVICE_STREAM_C2D_REQUEST_CALLBACK streamRequestCallback, const void* context);
```

**SRS_IOTHUBCLIENT_LL_09_011: [** If `iotHubClientHandle` is NULL, `IoTHubClientCore_LL_SetStreamRequestCallback` shall return IOTHUB_CLIENT_INVALID_ARG. **]**

**SRS_IOTHUBCLIENT_LL_09_012: [** The transport's `IoTHubTransport_SetStreamRequestCallback` shall be invoked passing `streamRequestCallback` and `context`. **]**

**SRS_IOTHUBCLIENT_LL_09_013: [** If `IoTHubTransport_SetStreamRequestCallback` fails, `IoTHubClientCore_LL_SetStreamRequestCallback` shall return IOTHUB_CLIENT_ERROR. **]**

**SRS_IOTHUBCLIENT_LL_09_014: [** If no failures occur `IoTHubClientCore_LL_SetStreamRequestCallback` shall return IOTHUB_CLIENT_OK. **]**


## IoTHubClientCore_LL_SendStreamResponse
```c
extern IOTHUB_CLIENT_RESULT IoTHubClientCore_LL_SendStreamResponse(IOTHUB_CLIENT_CORE_LL_HANDLE iotHubClientHandle, DEVICE_STREAM_C2D_RESPONSE* response);
```
**SRS_IOTHUBCLIENT_LL_09_015: [** If `iotHubClientHandle` or `response` are NULL, `IoTHubClientCore_LL_SendStreamResponse` shall return IOTHUB_CLIENT_INVALID_ARG. **]**
**SRS_IOTHUBCLIENT_LL_09_016: [** The transport's `IoTHubTransport_SendStreamResponse` shall be invoked passing `response`. **]**
**SRS_IOTHUBCLIENT_LL_09_017: [** If `IoTHubTransport_SendStreamResponse` fails, `IoTHubClientCore_LL_SendStreamResponse` shall return IOTHUB_CLIENT_ERROR. **]**
**SRS_IOTHUBCLIENT_LL_09_018: [** If no failures occur `IoTHubClientCore_LL_SendStreamResponse` shall return IOTHUB_CLIENT_OK. **]**
39 changes: 39 additions & 0 deletions iothub_client/devdoc/requirement_docs/iothubclient_requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ extern IOTHUB_CLIENT_RESULT IoTHubClientCore_GetDeviceTwinAsync(IOTHUB_CLIENT_LL
extern IOTHUB_CLIENT_RESULT IoTHubClient_SetDeviceMethodCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback);
unsigned char* payload, IOTHUB_CLIENT_IOTHUB_METHOD_EXECUTE_CALLBACK iotHubExecuteCallback, void* userContextCallback);
extern IOTHUB_CLIENT_RESULT IoTHubClient_SetDeviceMethodCallback_Ex(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inboundDeviceMethodCallback, void* userContextCallback);

## Device Stream
extern IOTHUB_CLIENT_RESULT IoTHubClientCore_SetStreamRequestCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, DEVICE_STREAM_C2D_REQUEST_CALLBACK streamRequestCallback, const void* context);
```
## IoTHubClient_GetVersionString
Expand Down Expand Up @@ -609,3 +612,39 @@ a value indicating whether to continue or abort the request.
**SRS_IOTHUBCLIENT_99_078: [** The thread shall call `IoTHubClient_LL_UploadMultipleBlocksToBlob` or `IoTHubClient_LL_UploadMultipleBlocksToBlobEx` passing the information packed in the structure. **]**

**SRS_IOTHUBCLIENT_99_077: [** If copying to the structure and spawning the thread succeeds, then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall return `IOTHUB_CLIENT_OK`. **]**


## IoTHubClientCore_SetStreamRequestCallback
```c
extern IOTHUB_CLIENT_RESULT IoTHubClientCore_SetStreamRequestCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, DEVICE_STREAM_C2D_REQUEST_CALLBACK streamRequestCallback, const void* context);
```
**SRS_IOTHUBCLIENT_09_001: [** If `iotHubClientHandle` is `NULL` the function shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. **]**
**SRS_IOTHUBCLIENT_09_002: [** `IoTHubClientCore_SetStreamRequestCallback` shall start the worker thread if it was not previously started. **]**
**SRS_IOTHUBCLIENT_09_003: [** If starting the thread fails, `IoTHubClientCore_SetStreamRequestCallback` shall return `IOTHUB_CLIENT_ERROR`. **]**
**SRS_IOTHUBCLIENT_09_004: [** The function shall acquire the lock to make the following block thread-safe. **]**
**SRS_IOTHUBCLIENT_09_005: [** If acquiring the lock fails, `IoTHubClientCore_SetStreamRequestCallback` shall return `IOTHUB_CLIENT_ERROR`. **]**
**SRS_IOTHUBCLIENT_09_006: [** `IoTHubClientCore_SetStreamRequestCallback` shall call `IoTHubClient_LL_SetStreamRequestCallback`, passing the `iothub_ll_device_stream_request_callback` **]**
**SRS_IOTHUBCLIENT_09_007: [** `IoTHubClientCore_SetStreamRequestCallback` shall return the result of `IoTHubClientCore_LL_SetStreamRequestCallback`. **]**
**SRS_IOTHUBCLIENT_09_008: [** `IoTHubClientCore_SetStreamRequestCallback` shall release the thread lock. **]**
### iothub_ll_device_stream_request_callback
```c
static DEVICE_STREAM_C2D_RESPONSE* iothub_ll_device_stream_request_callback(DEVICE_STREAM_C2D_REQUEST* request, const void* context);
```

**SRS_IOTHUBCLIENT_09_017: [** If `request` or `context` are `NULL` the function shall fail and return a response rejecting the stream request. **]**

**SRS_IOTHUBCLIENT_09_018: [** The stream request and user context shall be added to the user callback list for async dispatching **]**

**SRS_IOTHUBCLIENT_09_019: [** If the stream request fails to be added to the callback list, the function shall fail and return a response rejecting the stream request. **]**


Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ extern const TRANSPORT_PROVIDER* HTTP_Protocol(void);
- IoTHubTransportHttp_Subscribe,
- IoTHubTransportHttp_Unsubscribe,
- IoTHubTransportHttp_DoWork,
- IoTHubTransportHttp_SetStreamRequestCallback,
- IoTHubTransportHttp_GetSendStatus,
- IotHubTransportHttp_Subscribe_InputQueue,
- IotHubTransportHttp_Unsubscribe_InputQueue
Expand Down Expand Up @@ -304,6 +305,15 @@ MultiDevTransportHttp shall perform the following actions on each device:
return;
## IoTHubTransportHttp_SetStreamRequestCallback
```c
static int IoTHubTransportHttp_SetStreamRequestCallback(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_INCOMING_STREAM_REQUEST_CALLBACK streamRequestCallback, void* context)
```

**SRS_TRANSPORTMULTITHTTP_09_005: [** IoTHubTransportHttp_SetStreamRequestCallback shall return a failure (non-zero value) as it does not support TCP streaming **]**


## IoTHubTransportHttp_Subscribe
```c
extern SUBSCRIBE_RESULT IoTHubTransportHttp_Subscribe(IOTHUB_DEVICE_HANDLE deviceHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK callback, void* context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ extern const TRANSPORT_PROVIDER* MQTT_Protocol(void);
- IoTHubTransportMqtt_Subscribe,
- IoTHubTransportMqtt_Unsubscribe,
- IoTHubTransportMqtt_DoWork,
- IotHubTransportMqtt_SetStreamRequestCallback,
- IotHubTransportMqtt_SendStreamResponse,
- IoTHubTransportMqtt_SetRetryPolicy,
- IoTHubTransportMqtt_GetSendStatus,
- IoTHubTransportMQTT_Subscribe_InputQueue,
Expand Down Expand Up @@ -178,6 +180,24 @@ void IoTHubTransportMqtt_DoWork(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_LL_HAN
**SRS_IOTHUB_MQTT_TRANSPORT_07_007: [** IoTHubTransportMqtt_DoWork shall call into the IoTHubMqttAbstract_DoWork function. **]**
### IotHubTransportMqtt_SetStreamRequestCallback
```c
static int IotHubTransportMqtt_SetStreamRequestCallback(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_INCOMING_STREAM_REQUEST_CALLBACK streamRequestCallback, void* context)
```

**SRS_IOTHUB_MQTT_TRANSPORT_09_008: [** IotHubTransportMqtt_SetStreamRequestCallback shall call into the IoTHubTransport_MQTT_Common_SetStreamRequestCallback function. **]**


### IotHubTransportMqtt_SendStreamResponse

```c
static int IotHubTransportMqtt_SendStreamResponse(IOTHUB_DEVICE_HANDLE handle, DEVICE_STREAM_C2D_RESPONSE* response);
```
**SRS_IOTHUB_MQTT_TRANSPORT_09_009: [** IotHubTransportMqtt_SendStreamResponse shall call into the IoTHubTransport_MQTT_Common_SendStreamResponse function. **]**
### IoTHubTransportMqtt_SetRetryPolicy
```c
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ extern const TRANSPORT_PROVIDER* MQTT_Protocol(void);
- IoTHubTransportMqtt_WS_Subscribe,
- IoTHubTransportMqtt_WS_Unsubscribe,
- IoTHubTransportMqtt_WS_DoWork,
- IotHubTransportMqtt_WS_SetStreamRequestCallback,
- IotHubTransportMqtt_WS_SendStreamResponse,
- IoTHubTransportMqtt_WS_SetRetryPolicy,
- IoTHubTransportMqtt_WS_GetSendStatus,
- IotHubTransportMqtt_WS_Subscribe_InputQueue,
Expand Down Expand Up @@ -193,6 +195,25 @@ void IoTHubTransportMqtt_WS_DoWork(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_LL_
**SRS_IOTHUB_MQTT_WEBSOCKET_TRANSPORT_07_007: [** IoTHubTransportMqtt_WS_DoWork shall call into the IoTHubTransport_MQTT_Common_DoWork function. **]**
### IotHubTransportMqtt_WS_SetStreamRequestCallback
```c
static int IotHubTransportMqtt_WS_SetStreamRequestCallback(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_INCOMING_STREAM_REQUEST_CALLBACK streamRequestCallback, void* context)
```

**SRS_IOTHUB_MQTT_TRANSPORT_09_010: [** IotHubTransportMqtt_WS_SetStreamRequestCallback shall call into the IoTHubTransport_MQTT_Common_SetStreamRequestCallback function. **]**


### IotHubTransportMqtt_WS_SendStreamResponse

```c
static int IotHubTransportMqtt_WS_SendStreamResponse(IOTHUB_DEVICE_HANDLE handle, DEVICE_STREAM_C2D_RESPONSE* response);
```
**SRS_IOTHUB_MQTT_TRANSPORT_09_011: [** IotHubTransportMqtt_WS_SendStreamResponse shall call into the IoTHubTransport_MQTT_Common_SendStreamResponse function. **]**
### IoTHubTransportMqtt_WS_SetRetryPolicy
```c
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extern int IoTHubTransport_AMQP_Common_SetRetryPolicy(TRANSPORT_LL_HANDLE handle
extern IOTHUB_DEVICE_HANDLE IoTHubTransport_AMQP_Common_Register(TRANSPORT_LL_HANDLE handle, const IOTHUB_DEVICE_CONFIG* device, IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, PDLIST_ENTRY waitingToSend);
extern void IoTHubTransport_AMQP_Common_Unregister(IOTHUB_DEVICE_HANDLE deviceHandle);
extern STRING_HANDLE IoTHubTransport_AMQP_Common_GetHostname(TRANSPORT_LL_HANDLE handle);

extern int IoTHubTransport_AMQP_Common_SetStreamRequestCallback(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_INCOMING_STREAM_REQUEST_CALLBACK streamRequestCallback, void* context);
```
Expand Down Expand Up @@ -543,3 +543,19 @@ void on_methods_unsubscribed(void* context)
```

**SRS_IOTHUBTRANSPORT_AMQP_METHODS_12_001: [** `on_methods_unsubscribed` calls iothubtransportamqp_methods_unsubscribe. **]**


### IoTHubTransport_AMQP_Common_SetStreamRequestCallback

```c
extern int IoTHubTransport_AMQP_Common_SetStreamRequestCallback(IOTHUB_DEVICE_HANDLE handle, IOTHUB_CLIENT_INCOMING_STREAM_REQUEST_CALLBACK streamRequestCallback, void* context);
```
**SRS_IOTHUBTRANSPORT_AMQP_COMMON_09_154: [** If `handle` or `streamRequestCallback` are NULL, a non-zero value shall be returned (failure) **]**
**SRS_IOTHUBTRANSPORT_AMQP_COMMON_09_155: [** device_set_stream_request_callback() shall be invoked for the registered device, passing `streamRequestCallback` and `context` **]**
**SRS_IOTHUBTRANSPORT_AMQP_COMMON_09_156: [** If device_set_stream_request_callback() fails, `IoTHubTransport_AMQP_Common_SetStreamRequestCallback` shall fail and return non-zero. **]**
**SRS_IOTHUBTRANSPORT_AMQP_COMMON_09_157: [** If no errors occur, `IoTHubTransport_AMQP_Common_SetStreamRequestCallback` shall return zero. **]**
Loading

0 comments on commit 5a46693

Please sign in to comment.