locked
Sending D2C Messages on Azure IoT Hub via Android using Android Studio RRS feed

  • Question

  • 'm working on sending a text from an Android smartphone through the hub to another device (Raspberry Pi). I have already tried sending from C# simulated device to the Pi and it was a success. Currently, I'm trying to integrate Azure IoT SDK in Android studio. So, I started from running sample android-sample from its GitHub but it has shown the following error:

    Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
    > com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/BCKEY.DSA
    File1: C:\Users\jimmy\.gradle\caches\modules-2\files-2.1\org.bouncycastle\bcpkix-jdk15on\1.47\cd204e6f26d2bbf65ff3a30de8831d3a1344e851\bcpkix-jdk15on-1.47.jar
    File2: C:\Users\jimmy\.gradle\caches\modules-2\files-2.1\org.bouncycastle\bcprov-jdk15on\1.47\b9a978600db6607a738f50e87082564b76a6ce9b\bcprov-jdk15on-1.47.jar

    I really don't know how to handle with this situation. I have read about Maven, managing dependencies, and a bit about Gradle, but that doesn't help me much except having more knowledge about them. How could I make it run properly? Or if there is easier way to do the job stated at the beginning, please advise.

    Thank you very much!

    Monday, January 16, 2017 10:59 AM

Answers

  • Hi Bearfinn,

    this is not an answer to your problem with Azure IoT SDK + Android studio, where you having as the next step from the here.

    Your primary goal is having a device-to-device communications via the Azure IoT Hub. Today, the Azure IoT Hub has built-in only communication patterns for device-to-cloud, cloud-to-device (known as C2D Messaging) and direct method call (sync call something like RPC call) to the device with MQTT support.

    The logical connectivity device-to-device must be implemented behind the Azure IoT Hub under your responsibility routing, etc. and a full transparently between the devices.

    For better understanding, the following screen snippet shows an example how can be done implementation of the device-to-device communication behind the Azure IoT Hub (in other words, from the service-facing endpoints):

    As you can see, the devices have an access to the Azure IoT Hub with there own identities to the device-facing endpoints. On the other side (behind the service-facing endpoint, they have an own service identity)

    The above picture shows an architectural concept of the device-to-device communications. The logical connectivity D2D is full transparent to each device in async manner.

    The above D2D Messaging concept is based on the non-telemetry data and C2D messaging. The non-telemetry data is routes to the Custom Endpoint based on the rule and buffered in the Service Bus Entity (for instance Queue).  The message is triggered from the Service Bus Queue by Azure Function and forwarded to the Azure IoT Hub service-facing C2D endpoint. After that, the device can obtained this C2D message from its device-facing endpoint.

    For your case, you can considered an Android device with a Https connectivity to the Azure IoT Hub, so you don't need to use any SDK, just REST API.

    the following screen snippet shows an example of the simulated Http Request (Android) to the Azure IoT Hub:

     

    I have highlighted some headers in the above request:

    iothub-app-location: BA       this header is for Azure IoT Hub Routes

    iothub-to:Device2      this header is for Azure Function for routing message to the specific device

    other headers are for correlation purposes

    Note, that the Azure IoT Hub must be configured for Routes this message to the Service Bus Queue.

    The following code snippet shows example of the Azure Function for forwarding a D2C message to the C2D message (small bridge):

    #r "Newtonsoft.Json"
    #r "Microsoft.ServiceBus"
    
    using System;
    using System.Configuration;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    using Microsoft.ServiceBus.Messaging;
    using Microsoft.Azure.Devices;
    using System.Linq;
    
    public static async Task Run(BrokeredMessage msg, TraceWriter log)
    {
        log.Info($"ServiceBus queue trigger function processed message: to={msg.To}, cid={msg.CorrelationId}, mid={msg.MessageId}");
    
        // no destionation device
        if (string.IsNullOrEmpty(msg.To))
            return;
    
        // copy payload
        Message c2dmsg = null;
        using (Stream bodyStream = msg.GetBody<Stream>())
        using (var ms = new MemoryStream())
        {
            bodyStream.CopyTo(ms);
            c2dmsg = new Message(ms.ToArray());
        }
    
        // copy properties
        c2dmsg.Ack = DeliveryAcknowledgement.None;
        c2dmsg.MessageId = msg.MessageId;
        c2dmsg.CorrelationId = msg.CorrelationId;
        foreach(var prop in msg.Properties)
        {
            if(prop.Key.StartsWith("iothub_connection_") || prop.Key.StartsWith("iothub-connection-")) continue;
            c2dmsg.Properties.Add(prop.Key, Convert.ToString(prop.Value));
        }
    
        // create proxy
        string connectionString = ConfigurationManager.AppSettings["myIoTHub2"];
        var client = ServiceClient.CreateFromConnectionString(connectionString);
    
        // send AMQP message
        await client.SendAsync(msg.To, c2dmsg);
    }

    project.json

    {
      "frameworks": {
        "net46":{
          "dependencies": {
            "Microsoft.Azure.Devices": "1.2.1"
          }
        }
       }
    }

    As you can see, the Azure Function creates a C2D message with DeliveryAcknowledgement.None. In this case the device application must handled the ack/watchdog pattern between the devices. In the other case, the service-facing endpoint for C2D Feedback messages can be used with the custom built worker role. (It will be nice to have this service-endpoint with an Azure Service Bus compatibility for better plumbing integration, but now we don't have it.)

    I hope this help you to understand a D2D communications via Azure IoT Hub.

    Thanks

    Roman 



    • Edited by Roman Kiss Tuesday, January 17, 2017 11:36 AM
    • Marked as answer by Bearfinn Friday, February 3, 2017 9:57 AM
    Tuesday, January 17, 2017 11:24 AM

All replies

  • Hi Bearfinn,

    this is not an answer to your problem with Azure IoT SDK + Android studio, where you having as the next step from the here.

    Your primary goal is having a device-to-device communications via the Azure IoT Hub. Today, the Azure IoT Hub has built-in only communication patterns for device-to-cloud, cloud-to-device (known as C2D Messaging) and direct method call (sync call something like RPC call) to the device with MQTT support.

    The logical connectivity device-to-device must be implemented behind the Azure IoT Hub under your responsibility routing, etc. and a full transparently between the devices.

    For better understanding, the following screen snippet shows an example how can be done implementation of the device-to-device communication behind the Azure IoT Hub (in other words, from the service-facing endpoints):

    As you can see, the devices have an access to the Azure IoT Hub with there own identities to the device-facing endpoints. On the other side (behind the service-facing endpoint, they have an own service identity)

    The above picture shows an architectural concept of the device-to-device communications. The logical connectivity D2D is full transparent to each device in async manner.

    The above D2D Messaging concept is based on the non-telemetry data and C2D messaging. The non-telemetry data is routes to the Custom Endpoint based on the rule and buffered in the Service Bus Entity (for instance Queue).  The message is triggered from the Service Bus Queue by Azure Function and forwarded to the Azure IoT Hub service-facing C2D endpoint. After that, the device can obtained this C2D message from its device-facing endpoint.

    For your case, you can considered an Android device with a Https connectivity to the Azure IoT Hub, so you don't need to use any SDK, just REST API.

    the following screen snippet shows an example of the simulated Http Request (Android) to the Azure IoT Hub:

     

    I have highlighted some headers in the above request:

    iothub-app-location: BA       this header is for Azure IoT Hub Routes

    iothub-to:Device2      this header is for Azure Function for routing message to the specific device

    other headers are for correlation purposes

    Note, that the Azure IoT Hub must be configured for Routes this message to the Service Bus Queue.

    The following code snippet shows example of the Azure Function for forwarding a D2C message to the C2D message (small bridge):

    #r "Newtonsoft.Json"
    #r "Microsoft.ServiceBus"
    
    using System;
    using System.Configuration;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    using Microsoft.ServiceBus.Messaging;
    using Microsoft.Azure.Devices;
    using System.Linq;
    
    public static async Task Run(BrokeredMessage msg, TraceWriter log)
    {
        log.Info($"ServiceBus queue trigger function processed message: to={msg.To}, cid={msg.CorrelationId}, mid={msg.MessageId}");
    
        // no destionation device
        if (string.IsNullOrEmpty(msg.To))
            return;
    
        // copy payload
        Message c2dmsg = null;
        using (Stream bodyStream = msg.GetBody<Stream>())
        using (var ms = new MemoryStream())
        {
            bodyStream.CopyTo(ms);
            c2dmsg = new Message(ms.ToArray());
        }
    
        // copy properties
        c2dmsg.Ack = DeliveryAcknowledgement.None;
        c2dmsg.MessageId = msg.MessageId;
        c2dmsg.CorrelationId = msg.CorrelationId;
        foreach(var prop in msg.Properties)
        {
            if(prop.Key.StartsWith("iothub_connection_") || prop.Key.StartsWith("iothub-connection-")) continue;
            c2dmsg.Properties.Add(prop.Key, Convert.ToString(prop.Value));
        }
    
        // create proxy
        string connectionString = ConfigurationManager.AppSettings["myIoTHub2"];
        var client = ServiceClient.CreateFromConnectionString(connectionString);
    
        // send AMQP message
        await client.SendAsync(msg.To, c2dmsg);
    }

    project.json

    {
      "frameworks": {
        "net46":{
          "dependencies": {
            "Microsoft.Azure.Devices": "1.2.1"
          }
        }
       }
    }

    As you can see, the Azure Function creates a C2D message with DeliveryAcknowledgement.None. In this case the device application must handled the ack/watchdog pattern between the devices. In the other case, the service-facing endpoint for C2D Feedback messages can be used with the custom built worker role. (It will be nice to have this service-endpoint with an Azure Service Bus compatibility for better plumbing integration, but now we don't have it.)

    I hope this help you to understand a D2D communications via Azure IoT Hub.

    Thanks

    Roman 



    • Edited by Roman Kiss Tuesday, January 17, 2017 11:36 AM
    • Marked as answer by Bearfinn Friday, February 3, 2017 9:57 AM
    Tuesday, January 17, 2017 11:24 AM
  • Thank you for the response, and sorry for my slow response too.

    May I ask further for some of the questions.

    1. Is IoT Hub the right solution for connecting numerous pairs of D2D devices which will need to store it on Database as transactions?

    2. Is Java SDK also an alternative to REST API for D2C Messaging?

    3. Why do we need CustomEndpoint if all the data is going to be send to the destination devices? Can I just use the same endpoint to connect to Azure Function module?

    Faithfully yours,
    Bearfinn

    Friday, February 3, 2017 10:02 AM
  • Hi Bearfinn,

    I do recommend to read the following:

      - What is Azure IoT Hub? where is noted, that:

    "Azure IoT Hub is a fully managed service that enables reliable and secure bidirectional communications between millions of IoT devices and a solution back end. Azure IoT Hub"

    The primary communication path for Azure IoT Hub is to ingest a telemetry data in the real-time and secure manner. This is a push model from the device to the cloud, where the stream telemetry data are buffered in the EventHub.

    Recently the Azure IoT Hub released a great feature such as Routes and Custom Endpoints with capabilities to decide a routing based on the rules where to push the device event either to the custom endpoint or to the default endpoint (such as built-in its Event Hub). Basically, the Azure IoT Hub has built-in a mechanism for filtering, selecting and sorting incoming events before their analyzing which it will save some money and increasing a performance on the pipeline processing. I have used this new feature on the D2D messaging concept.

    Another document for reading and understanding is IoT Hub quotas and throttling regardless to your business model needs and your question #1.

    Note, that the Azure IoT Hub has built-in a secure and reliable connectivity with management service per each device (registry, device twin state, post process jobs, direct method call on device, upload blob files, etc.), so adding the worker role with a azure storage for bridging a non-telemetry messages between the devices is just a custom cloud backend extension to the Azure IoT Hub. Your custom extension has a responsibility which device can talk to another device, that was a probably the point of the Microsoft IoT infrastructure.

    Finally, one more link to your question (#2), see the azure-iot-sdks.

    Thanks

    Roman



    • Edited by Roman Kiss Tuesday, February 7, 2017 10:07 AM
    Tuesday, February 7, 2017 10:03 AM