demo project

Dependencies:   AX-12A Dynamixel mbed iothub_client EthernetInterface NTPClient ConfigFile SDFileSystem iothub_amqp_transport mbed-rtos proton-c-mbed wolfSSL

Revision:
4:36a4eceb1b7f
Child:
5:36916b1c5a06
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IothubRobotArm.cpp	Wed Dec 23 18:34:06 2015 +0000
@@ -0,0 +1,254 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "mbed.h"
+#include "rtos.h"
+
+#include "iothub_client.h"
+#include "iothub_message.h"
+#include "crt_abstractions.h"
+#include "iothubtransportamqp.h"
+#include "MeasureBuf.h"
+#include "IothubRobotArm.h"
+#include "IothubSerial.h"
+
+#ifdef MBED_BUILD_TIMESTAMP
+#include "certs.h"
+#endif // MBED_BUILD_TIMESTAMP
+
+static const char* connectionString = "HostName=HenryrIot.azure-devices.net;DeviceId=RobotArm;SharedAccessKey=FUTqsobGrV0ldHbnmOKluN6W90FG1G5z/jnhz+Gr53k=";
+static int callbackCounter;
+static int msgNumber;
+
+DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_CONFIRMATION_RESULT, IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES);
+
+typedef struct EVENT_INSTANCE_TAG
+{
+    IOTHUB_MESSAGE_HANDLE messageHandle;
+    int messageTrackingId;  // For tracking the messages within the user callback.
+} EVENT_INSTANCE;
+
+static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
+{
+    int* counter = (int*)userContextCallback;
+    const char* buffer;
+    size_t size;
+
+    if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) == IOTHUB_MESSAGE_OK)
+    {
+        (void)printf("Received Message [%d] with Data: <<<%.*s>>> & Size=%d\r\n", *counter, (int)size, buffer, (int)size);
+    }
+
+    // Retrieve properties from the message
+    MAP_HANDLE mapProperties = IoTHubMessage_Properties(message);
+    if (mapProperties != NULL)
+    {
+        const char*const* keys;
+        const char*const* values;
+        size_t propertyCount = 0;
+        if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
+        {
+            if (propertyCount > 0)
+            {
+                printf("Message Properties:\r\n");
+                for (size_t index = 0; index < propertyCount; index++)
+                {
+                    printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
+                }
+                printf("\r\n");
+            }
+        }
+    }
+
+    /* Some device specific action code goes here... */
+    (*counter)++;
+    return IOTHUBMESSAGE_ACCEPTED;
+}
+
+static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
+{
+    EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
+    (void)printf("Confirmation[%d] received for message tracking id = %d with result = %s\r\n", callbackCounter, eventInstance->messageTrackingId, ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
+    /* Some device specific action code goes here... */
+    callbackCounter++;
+    IoTHubMessage_Destroy(eventInstance->messageHandle);
+    
+    if (callbackCounter == msgNumber)
+    {
+        // call SendMeasurements again in case more to send
+    }
+}
+
+// IoT Hub thread
+static Thread* IotThread = NULL;
+static bool IotThreadClose;
+
+// entry point for ITHub sending thread
+void IothubThread(void const *args)
+{
+    (void)printf("Iothub thread start\r\n");
+    IotThreadClose = false;
+    IothubRobotArm iotRobot;
+    iotRobot.Init();
+    
+    while (1)
+    {
+        (void)printf("Iothub thread wait signal\r\n");
+        osEvent ev = Thread::signal_wait(IS_SendStatus);
+        //if ((ev.value.signals & IS_Close)  == IS_Close)
+        if (IotThreadClose)
+        {
+            (void)printf("Iothub thread close signal\r\n");
+            iotRobot.Terminate();
+            break;
+        }
+        else
+        {
+            if ((ev.value.signals & IS_SendStatus) == IS_SendStatus)
+            {
+                (void)printf("Iothub thread send status signal\r\n");
+                iotRobot.SendMeasurements();
+            }
+            else
+            {
+                (void)printf("Iothub thread unknown signal\r\n");
+            }
+        }
+    }
+}
+
+
+bool StartIothubThread()
+{
+    IotThread = new Thread(IothubThread, NULL, osPriorityLow); 
+    return true;
+}
+
+bool SendIothubMeasurements()
+{
+    (void)printf("Iothub thread signal to send data\r\n");
+    IotThread->signal_set(IS_SendStatus);
+    return true;
+}
+
+void EndIothubThread()
+{
+    IotThreadClose = true;
+    IotThread->signal_set(IS_SendStatus);
+}
+
+IothubRobotArm::IothubRobotArm()
+{
+    iotHubClientHandle = NULL;
+}
+
+bool IothubRobotArm::Init()
+{
+    int receiveContext = 0;
+    callbackCounter = 0;
+    msgNumber = 0;
+    
+    // in case calling init twice without terminate
+    Terminate();
+    
+    (void)printf("Starting the IoTHub RobotArm sample AMQP...\r\n");
+
+    if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol)) == NULL)
+    {
+        (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
+        return false;
+    }
+    else
+    {
+#ifdef MBED_BUILD_TIMESTAMP
+        (void)printf("INFO: IoTHubClient_SetOption\r\n");
+        // For mbed add the certificate information
+        if (IoTHubClient_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
+        {
+            printf("failure to set option \"TrustedCerts\"\r\n");
+            return false;
+        }
+#endif // MBED_BUILD_TIMESTAMP
+
+        (void)printf("INFO: IoTHubClient_SetMessageCallback\r\n");
+        /* Setting Message call back, so we can receive Commands. */
+        if (IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
+        {
+            (void)printf("ERROR: IoTHubClient_SetMessageCallback..........FAILED!\r\n");
+            return false;
+        }
+        else
+        {
+            (void)printf("IoTHubClient_SetMessageCallback...successful.\r\n");
+        }
+    }
+    return true;
+}
+
+void IothubRobotArm::Terminate()
+{
+    if (iotHubClientHandle != NULL)
+    {
+        IoTHubClient_Destroy(iotHubClientHandle);
+        iotHubClientHandle = NULL;
+    }
+}
+
+#define MESSAGE_LEN 1024
+static char msgText[MESSAGE_LEN];
+static char propText[MESSAGE_LEN];
+#define MESSAGE_COUNT 10
+
+void IothubRobotArm::SendMeasurements(void)
+{
+    EVENT_INSTANCE messages[MESSAGE_COUNT];
+
+    int i = 0;
+    
+    // send until circular buf empty or send buffer max
+    while (i < MESSAGE_COUNT)
+    {
+        int msglen = msgSerialize.MeasureBufToString(msgText, MESSAGE_LEN);
+
+        if (msglen > 0)
+        {
+            (void)printf("Sending data bytes %d\r\n", msglen);
+            if ((messages[i].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, msglen)) == NULL)
+            {
+                (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
+            }
+            else
+            {
+                messages[i].messageTrackingId = msgNumber;
+                
+                MAP_HANDLE propMap = IoTHubMessage_Properties(messages[i].messageHandle);
+                sprintf_s(propText, sizeof(propText), "PropMsg_%d", msgNumber);
+                if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
+                {
+                    (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
+                }
+
+                if (IoTHubClient_SendEventAsync(iotHubClientHandle, messages[i].messageHandle, SendConfirmationCallback, &messages[i]) != IOTHUB_CLIENT_OK)
+                {
+                    (void)printf("ERROR: IoTHubClient_SendEventAsync..........FAILED!\r\n");
+                }
+                else
+                {
+                    (void)printf("IoTHubClient_SendEventAsync accepted data for transmission to IoT Hub. bytes: %d\r\n", msglen);
+                }
+                msgNumber++;
+            }
+        }
+        else if (msglen == 0)
+        {
+            (void)printf("No more data to send \r\n");
+            break;
+        }
+        else if (msglen < 0)
+        {
+            (void)printf("ERROR: Serialized message too big for buffer\r\n");
+            break;
+        }
+    } // while
+
+}