TCP in Azure IoT Hub

0 votes
Azure IoT Hub Supports AMQP, MQTT, HTTP protocols and to customize these protocols, there is the Azure IoT protocol gateway. I can also find good samples on MQTT protocol customization. But, I need some sample codes for TCP based protocol customization using Azure IoT Protocol Gateway.

So, what I need is an example using the Azure Protocol Gateway to support a proprietary TCP-based protocol. And currently, the Azure IoT Hub just supports AMQP, MQTT, and HTTP. While these protocols rely on TCP, the hub doesn't support direct TCP connection without the extra layer of AMQP, MQTT or HTTP. So, I'm looking for a basic example of a custom TCP based protocol.

Like, say, a basic device that can only send some proprietary payload through TCP on a given IP address/port. So, it will need a gateway customization allowing this device to send data to the hub. Plus, the current code of the protocol gateway is poorly designed as it heavily relies on MQTT.
Oct 11, 2018 in IoT (Internet of Things) by Bharani
• 4,560 points
577 views

1 answer to this question.

0 votes

The default Protocol Gateway samples are indeed confusing because of all the MQTT code. The protocol gateway works by 'simulating' an IoT Hub connection for each custom protocol device you connect to the gateway.

To do this translation from the TCP device to an IoTHub device, you will first need a connection to the IoT Hub from the device. This is the gateway part and below are the core essentials for this IoTHubConnection.

namespace GatewayTest
{
    using System;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using DotNetty.Buffers;
    using Microsoft.Azure.Devices.ProtocolGateway.Identity;
    using Microsoft.Azure.Devices.ProtocolGateway.IotHubClient;
    using Microsoft.Azure.Devices.ProtocolGateway.Messaging;

    public class IoTHubConnection : IMessagingChannel<IMessage>
    {
        private readonly string iotHubHostName;
        private readonly Func<IDeviceIdentity, Task<IMessagingServiceClient>> deviceClientFactory;
        private readonly Func<string, Task> onMessage;
        private IMessagingServiceClient deviceClient;
        private IDeviceIdentity deviceIdentity;

        public IoTHubConnection(
            string iotHubHostName,
            Func<IDeviceIdentity, Task<IMessagingServiceClient>> deviceClientFactory,
            Func<string, Task> onMessage)
        {
            this.iotHubHostName = iotHubHostName;
            this.deviceClientFactory = deviceClientFactory;
            this.onMessage = onMessage;
        }

        public event EventHandler CapabilitiesChanged;

        public async Task OpenAsync(string deviceId, string deviceKey)
        {
            this.deviceIdentity = this.GetDeviceIdentity(deviceId, deviceKey);
            if (this.deviceIdentity != UnauthenticatedDeviceIdentity.Instance)
            {
                this.deviceClient = await this.deviceClientFactory(this.deviceIdentity);
                this.deviceClient.BindMessagingChannel(this);
            }
        }

        public async Task CloseAsync()
        {
            await this.deviceClient.DisposeAsync(null);
            this.deviceClient = null;
        }

        public void Handle(IMessage message)
        {
            var messageBody = message.Payload.ToString(Encoding.UTF8);

            this.onMessage(messageBody)

            this.deviceClient.CompleteAsync(message.Id);
        }

        public Task SendMessage(string message)
        {
            var buffer = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(message));
            var deviceMessage = this.deviceClient.CreateMessage($"devices/{this.deviceIdentity.Id}/messages/events", buffer);
            return this.deviceClient.SendAsync(deviceMessage);
        }

        protected virtual void OnCapabilitiesChanged(EventArgs e)
        {
            this.CapabilitiesChanged?.Invoke(this, e);
        }

        private IDeviceIdentity GetDeviceIdentity(string userName, string deviceKey)
        {
            IotHubDeviceIdentity ideviceIdentity;
            if (!IotHubDeviceIdentity.TryParse($"{this.iotHubHostName}/{userName}", out ideviceIdentity))
            {
                return UnauthenticatedDeviceIdentity.Instance;
            }

            ideviceIdentity.WithDeviceKey(deviceKey);
            return ideviceIdentity;
        }
    }
}

Implement the deviceClientFactory callback method as shown below and in this line in the ProtocolGateway repo in Github: https://github.com/Azure/azure-iot-protocol-gateway/blob/45d5b6ef57dce0027eef467cf14ac1ab6e3a358a/host/ProtocolGateway.Host.Common/Bootstrapper.cs#L149

deviceClientFactory = IotHubClient.PreparePoolFactory(
    "IotHubConnectionString",
    400,
    TimeSpan.FromMinutes(3),
    iotHubClientSettings,
    PooledByteBufferAllocator.Default,
    new ConfigurableMessageAddressConverter("TopicNameConversion"));

Upon connecting a Tcp Device to the protocol, make sure you create an instance of this IoTHubConnection and send messages from the Device to the IoTHubConnection and vice versa. The code below is a simple version of how it should be done.

private const int BufferSize = 1024;
private byte[] buffer = new byte[BufferSize];
private IoTHubConnection ioTHubConnection;
private NetworkStream stream;

private async Task Start()
{
    listener = new TcpListener(IPAddress.Any, port);
    listener.Start();

    var client = await listener.AcceptTcpClientAsync();
    ioTHubConnection = new IoTHubConnection("IoTHubName", deviceClientFactory, OnIoTHubMessage);
    stream = client.GetStream();

    // Read DeviceId and DeviceKey from some sort of StartConnection-message send by the TcpClient.
    await ioTHubConnection.OpenAsync("DeviceId", "DeviceKey");

    stream.BeginRead(buffer, 0, BufferSize, ReadTcpStreamCallback, null);
}

private void ReadTcpStreamCallback(IAsyncResult ar)
{
    var bytesRead = stream.EndRead(ar);

    if (bytesRead > 0)
    {
        var message = System.Text.Encoding.ASCII.GetString(result);

        ioTHubConnection.SendMessage(message);

        // Read again.
        stream.BeginRead(buffer, 0, BufferSize, ReadTcpStreamCallback, null);
    }
}

private async Task OnIoTHubMessage(string message)
answered Oct 11, 2018 by DataKing99
• 8,130 points

Hello, what should i to pass in this parameter 

new ConfigurableMessageAddressConverter(???)) .i dont really get it.

Related Questions In IoT (Internet of Things)

0 votes
1 answer

Control LED Blinking Using Java in Azure IoT Hub

Your description of what you did is ...READ MORE

answered Sep 5, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
176 views
0 votes
1 answer

Certificate issue in Azure IoT Hub

I've fixed this problem: The configured CA certificate ...READ MORE

answered Oct 11, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
653 views
0 votes
1 answer

Create Azure IoT using ARM Template in Azure

It is not recommended to deploy the ...READ MORE

answered Sep 5, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
204 views
0 votes
1 answer
0 votes
1 answer
0 votes
1 answer

Displaying Table Schema using Power BI with Azure IoT Hub

Answering your first question, Event Hubs are ...READ MORE

answered Aug 1, 2018 in IoT (Internet of Things) by nirvana
• 3,060 points
114 views
0 votes
1 answer

Azure - What service to use for Arduino data (iot)

That's because the two services do completely ...READ MORE

answered Aug 1, 2018 in IoT (Internet of Things) by anonymous2
• 4,280 points
132 views
0 votes
2 answers

Azure IoT Hub Operations Monitoring

Hi, Can you tell which device you ...READ MORE

answered Jan 4 in IoT (Internet of Things) by Varul
• 140 points
213 views
0 votes
1 answer

How to use the data I receive from Azure IoT Hub?

The payload you receive will be a ...READ MORE

answered Aug 1, 2018 in IoT (Internet of Things) by DataKing99
• 8,130 points
653 views
0 votes
1 answer

Testing if messages from my Device is reaching the Azure IoT Hub?

Download the Device Explorer open source tool ...READ MORE

answered Aug 10, 2018 in IoT (Internet of Things) by DataKing99
• 8,130 points
723 views