demo project
Dependencies: AX-12A Dynamixel mbed iothub_client EthernetInterface NTPClient ConfigFile SDFileSystem iothub_amqp_transport mbed-rtos proton-c-mbed wolfSSL
Diff: IothubRobotArm.cpp
- 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 + +}