demo project

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

Committer:
henryrawas
Date:
Tue Dec 29 23:31:28 2015 +0000
Revision:
7:6723f6887d00
Parent:
5:36916b1c5a06
Child:
8:d98e2dec0f40
motion block alerts, more commands

Who changed what in which revision?

UserRevisionLine numberNew contents of line
henryrawas 4:36a4eceb1b7f 1 // Copyright (c) Microsoft. All rights reserved.
henryrawas 4:36a4eceb1b7f 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
henryrawas 4:36a4eceb1b7f 3
henryrawas 4:36a4eceb1b7f 4 #include "mbed.h"
henryrawas 4:36a4eceb1b7f 5 #include "rtos.h"
henryrawas 4:36a4eceb1b7f 6
henryrawas 4:36a4eceb1b7f 7 #include "iothub_client.h"
henryrawas 4:36a4eceb1b7f 8 #include "iothub_message.h"
henryrawas 4:36a4eceb1b7f 9 #include "crt_abstractions.h"
henryrawas 4:36a4eceb1b7f 10 #include "iothubtransportamqp.h"
henryrawas 4:36a4eceb1b7f 11 #include "MeasureBuf.h"
henryrawas 4:36a4eceb1b7f 12 #include "IothubRobotArm.h"
henryrawas 4:36a4eceb1b7f 13 #include "IothubSerial.h"
henryrawas 4:36a4eceb1b7f 14
henryrawas 4:36a4eceb1b7f 15 #ifdef MBED_BUILD_TIMESTAMP
henryrawas 4:36a4eceb1b7f 16 #include "certs.h"
henryrawas 4:36a4eceb1b7f 17 #endif // MBED_BUILD_TIMESTAMP
henryrawas 4:36a4eceb1b7f 18
henryrawas 5:36916b1c5a06 19 // TODO: move to config file
henryrawas 4:36a4eceb1b7f 20 static const char* connectionString = "HostName=HenryrIot.azure-devices.net;DeviceId=RobotArm;SharedAccessKey=FUTqsobGrV0ldHbnmOKluN6W90FG1G5z/jnhz+Gr53k=";
henryrawas 5:36916b1c5a06 21
henryrawas 4:36a4eceb1b7f 22
henryrawas 4:36a4eceb1b7f 23 DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_CONFIRMATION_RESULT, IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES);
henryrawas 4:36a4eceb1b7f 24
henryrawas 4:36a4eceb1b7f 25 typedef struct EVENT_INSTANCE_TAG
henryrawas 4:36a4eceb1b7f 26 {
henryrawas 4:36a4eceb1b7f 27 IOTHUB_MESSAGE_HANDLE messageHandle;
henryrawas 4:36a4eceb1b7f 28 int messageTrackingId; // For tracking the messages within the user callback.
henryrawas 4:36a4eceb1b7f 29 } EVENT_INSTANCE;
henryrawas 4:36a4eceb1b7f 30
henryrawas 5:36916b1c5a06 31 // message buffers to use
henryrawas 5:36916b1c5a06 32 #define MESSAGE_LEN 1024
henryrawas 5:36916b1c5a06 33 static char msgText[MESSAGE_LEN];
henryrawas 7:6723f6887d00 34 //static char propText[MESSAGE_LEN];
henryrawas 7:6723f6887d00 35
henryrawas 5:36916b1c5a06 36 #define MESSAGE_COUNT 10
henryrawas 5:36916b1c5a06 37 EVENT_INSTANCE messages[MESSAGE_COUNT];
henryrawas 5:36916b1c5a06 38
henryrawas 5:36916b1c5a06 39 // context for send & receive
henryrawas 5:36916b1c5a06 40 static int receiveContext;
henryrawas 5:36916b1c5a06 41 static int callbackCounter;
henryrawas 5:36916b1c5a06 42 static int msgNumber;
henryrawas 5:36916b1c5a06 43
henryrawas 7:6723f6887d00 44
henryrawas 5:36916b1c5a06 45 static IOTHUB_CLIENT_HANDLE iotHubClientHandle;
henryrawas 5:36916b1c5a06 46
henryrawas 5:36916b1c5a06 47
henryrawas 5:36916b1c5a06 48 extern void ControlArm(const char* cmd);
henryrawas 5:36916b1c5a06 49
henryrawas 4:36a4eceb1b7f 50 static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
henryrawas 4:36a4eceb1b7f 51 {
henryrawas 4:36a4eceb1b7f 52 int* counter = (int*)userContextCallback;
henryrawas 4:36a4eceb1b7f 53 const char* buffer;
henryrawas 4:36a4eceb1b7f 54 size_t size;
henryrawas 5:36916b1c5a06 55 char cmdbuf[20];
henryrawas 5:36916b1c5a06 56
henryrawas 4:36a4eceb1b7f 57 if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) == IOTHUB_MESSAGE_OK)
henryrawas 4:36a4eceb1b7f 58 {
henryrawas 5:36916b1c5a06 59 (void)printf("Received Message [%d] with Data: <%.*s> & Size=%d\r\n", (int)size, *counter, buffer, (int)size);
henryrawas 5:36916b1c5a06 60 int slen = size;
henryrawas 5:36916b1c5a06 61 if (size >= 20)
henryrawas 5:36916b1c5a06 62 slen = 19;
henryrawas 5:36916b1c5a06 63 strncpy(cmdbuf, buffer, slen);
henryrawas 5:36916b1c5a06 64 cmdbuf[slen] = 0;
henryrawas 5:36916b1c5a06 65 ControlArm((const char*)cmdbuf);
henryrawas 4:36a4eceb1b7f 66 }
henryrawas 4:36a4eceb1b7f 67
henryrawas 4:36a4eceb1b7f 68 // Retrieve properties from the message
henryrawas 4:36a4eceb1b7f 69 MAP_HANDLE mapProperties = IoTHubMessage_Properties(message);
henryrawas 4:36a4eceb1b7f 70 if (mapProperties != NULL)
henryrawas 4:36a4eceb1b7f 71 {
henryrawas 4:36a4eceb1b7f 72 const char*const* keys;
henryrawas 4:36a4eceb1b7f 73 const char*const* values;
henryrawas 4:36a4eceb1b7f 74 size_t propertyCount = 0;
henryrawas 4:36a4eceb1b7f 75 if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
henryrawas 4:36a4eceb1b7f 76 {
henryrawas 4:36a4eceb1b7f 77 if (propertyCount > 0)
henryrawas 4:36a4eceb1b7f 78 {
henryrawas 4:36a4eceb1b7f 79 printf("Message Properties:\r\n");
henryrawas 4:36a4eceb1b7f 80 for (size_t index = 0; index < propertyCount; index++)
henryrawas 4:36a4eceb1b7f 81 {
henryrawas 4:36a4eceb1b7f 82 printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
henryrawas 4:36a4eceb1b7f 83 }
henryrawas 4:36a4eceb1b7f 84 printf("\r\n");
henryrawas 4:36a4eceb1b7f 85 }
henryrawas 4:36a4eceb1b7f 86 }
henryrawas 4:36a4eceb1b7f 87 }
henryrawas 4:36a4eceb1b7f 88
henryrawas 4:36a4eceb1b7f 89 /* Some device specific action code goes here... */
henryrawas 4:36a4eceb1b7f 90 (*counter)++;
henryrawas 4:36a4eceb1b7f 91 return IOTHUBMESSAGE_ACCEPTED;
henryrawas 4:36a4eceb1b7f 92 }
henryrawas 4:36a4eceb1b7f 93
henryrawas 4:36a4eceb1b7f 94 static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
henryrawas 4:36a4eceb1b7f 95 {
henryrawas 4:36a4eceb1b7f 96 EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
henryrawas 4:36a4eceb1b7f 97 (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));
henryrawas 7:6723f6887d00 98
henryrawas 4:36a4eceb1b7f 99 callbackCounter++;
henryrawas 4:36a4eceb1b7f 100 IoTHubMessage_Destroy(eventInstance->messageHandle);
henryrawas 4:36a4eceb1b7f 101
henryrawas 4:36a4eceb1b7f 102 if (callbackCounter == msgNumber)
henryrawas 4:36a4eceb1b7f 103 {
henryrawas 4:36a4eceb1b7f 104 // call SendMeasurements again in case more to send
henryrawas 7:6723f6887d00 105 SendIothubData();
henryrawas 4:36a4eceb1b7f 106 }
henryrawas 4:36a4eceb1b7f 107 }
henryrawas 4:36a4eceb1b7f 108
henryrawas 7:6723f6887d00 109
henryrawas 4:36a4eceb1b7f 110 // IoT Hub thread
henryrawas 4:36a4eceb1b7f 111 static Thread* IotThread = NULL;
henryrawas 4:36a4eceb1b7f 112 static bool IotThreadClose;
henryrawas 4:36a4eceb1b7f 113
henryrawas 4:36a4eceb1b7f 114 // entry point for ITHub sending thread
henryrawas 4:36a4eceb1b7f 115 void IothubThread(void const *args)
henryrawas 4:36a4eceb1b7f 116 {
henryrawas 4:36a4eceb1b7f 117 (void)printf("Iothub thread start\r\n");
henryrawas 4:36a4eceb1b7f 118 IotThreadClose = false;
henryrawas 4:36a4eceb1b7f 119 IothubRobotArm iotRobot;
henryrawas 4:36a4eceb1b7f 120 iotRobot.Init();
henryrawas 4:36a4eceb1b7f 121
henryrawas 4:36a4eceb1b7f 122 while (1)
henryrawas 4:36a4eceb1b7f 123 {
henryrawas 4:36a4eceb1b7f 124 (void)printf("Iothub thread wait signal\r\n");
henryrawas 4:36a4eceb1b7f 125 osEvent ev = Thread::signal_wait(IS_SendStatus);
henryrawas 4:36a4eceb1b7f 126 //if ((ev.value.signals & IS_Close) == IS_Close)
henryrawas 4:36a4eceb1b7f 127 if (IotThreadClose)
henryrawas 4:36a4eceb1b7f 128 {
henryrawas 4:36a4eceb1b7f 129 (void)printf("Iothub thread close signal\r\n");
henryrawas 4:36a4eceb1b7f 130 iotRobot.Terminate();
henryrawas 4:36a4eceb1b7f 131 break;
henryrawas 4:36a4eceb1b7f 132 }
henryrawas 4:36a4eceb1b7f 133 else
henryrawas 4:36a4eceb1b7f 134 {
henryrawas 4:36a4eceb1b7f 135 if ((ev.value.signals & IS_SendStatus) == IS_SendStatus)
henryrawas 4:36a4eceb1b7f 136 {
henryrawas 4:36a4eceb1b7f 137 iotRobot.SendMeasurements();
henryrawas 4:36a4eceb1b7f 138 }
henryrawas 4:36a4eceb1b7f 139 else
henryrawas 4:36a4eceb1b7f 140 {
henryrawas 4:36a4eceb1b7f 141 (void)printf("Iothub thread unknown signal\r\n");
henryrawas 4:36a4eceb1b7f 142 }
henryrawas 4:36a4eceb1b7f 143 }
henryrawas 4:36a4eceb1b7f 144 }
henryrawas 4:36a4eceb1b7f 145 }
henryrawas 4:36a4eceb1b7f 146
henryrawas 4:36a4eceb1b7f 147
henryrawas 4:36a4eceb1b7f 148 bool StartIothubThread()
henryrawas 4:36a4eceb1b7f 149 {
henryrawas 4:36a4eceb1b7f 150 IotThread = new Thread(IothubThread, NULL, osPriorityLow);
henryrawas 4:36a4eceb1b7f 151 return true;
henryrawas 4:36a4eceb1b7f 152 }
henryrawas 4:36a4eceb1b7f 153
henryrawas 7:6723f6887d00 154 bool SendIothubData()
henryrawas 4:36a4eceb1b7f 155 {
henryrawas 4:36a4eceb1b7f 156 IotThread->signal_set(IS_SendStatus);
henryrawas 4:36a4eceb1b7f 157 return true;
henryrawas 4:36a4eceb1b7f 158 }
henryrawas 4:36a4eceb1b7f 159
henryrawas 4:36a4eceb1b7f 160 void EndIothubThread()
henryrawas 4:36a4eceb1b7f 161 {
henryrawas 4:36a4eceb1b7f 162 IotThreadClose = true;
henryrawas 4:36a4eceb1b7f 163 IotThread->signal_set(IS_SendStatus);
henryrawas 4:36a4eceb1b7f 164 }
henryrawas 4:36a4eceb1b7f 165
henryrawas 4:36a4eceb1b7f 166 IothubRobotArm::IothubRobotArm()
henryrawas 4:36a4eceb1b7f 167 {
henryrawas 4:36a4eceb1b7f 168 iotHubClientHandle = NULL;
henryrawas 4:36a4eceb1b7f 169 }
henryrawas 4:36a4eceb1b7f 170
henryrawas 4:36a4eceb1b7f 171 bool IothubRobotArm::Init()
henryrawas 4:36a4eceb1b7f 172 {
henryrawas 5:36916b1c5a06 173 receiveContext = 0;
henryrawas 4:36a4eceb1b7f 174 callbackCounter = 0;
henryrawas 4:36a4eceb1b7f 175 msgNumber = 0;
henryrawas 4:36a4eceb1b7f 176
henryrawas 4:36a4eceb1b7f 177 // in case calling init twice without terminate
henryrawas 4:36a4eceb1b7f 178 Terminate();
henryrawas 4:36a4eceb1b7f 179
henryrawas 4:36a4eceb1b7f 180 (void)printf("Starting the IoTHub RobotArm sample AMQP...\r\n");
henryrawas 4:36a4eceb1b7f 181
henryrawas 4:36a4eceb1b7f 182 if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString(connectionString, AMQP_Protocol)) == NULL)
henryrawas 4:36a4eceb1b7f 183 {
henryrawas 4:36a4eceb1b7f 184 (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
henryrawas 4:36a4eceb1b7f 185 return false;
henryrawas 4:36a4eceb1b7f 186 }
henryrawas 4:36a4eceb1b7f 187 else
henryrawas 4:36a4eceb1b7f 188 {
henryrawas 4:36a4eceb1b7f 189 #ifdef MBED_BUILD_TIMESTAMP
henryrawas 4:36a4eceb1b7f 190 (void)printf("INFO: IoTHubClient_SetOption\r\n");
henryrawas 4:36a4eceb1b7f 191 // For mbed add the certificate information
henryrawas 4:36a4eceb1b7f 192 if (IoTHubClient_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
henryrawas 4:36a4eceb1b7f 193 {
henryrawas 4:36a4eceb1b7f 194 printf("failure to set option \"TrustedCerts\"\r\n");
henryrawas 4:36a4eceb1b7f 195 return false;
henryrawas 4:36a4eceb1b7f 196 }
henryrawas 4:36a4eceb1b7f 197 #endif // MBED_BUILD_TIMESTAMP
henryrawas 4:36a4eceb1b7f 198
henryrawas 4:36a4eceb1b7f 199 (void)printf("INFO: IoTHubClient_SetMessageCallback\r\n");
henryrawas 4:36a4eceb1b7f 200 /* Setting Message call back, so we can receive Commands. */
henryrawas 4:36a4eceb1b7f 201 if (IoTHubClient_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
henryrawas 4:36a4eceb1b7f 202 {
henryrawas 4:36a4eceb1b7f 203 (void)printf("ERROR: IoTHubClient_SetMessageCallback..........FAILED!\r\n");
henryrawas 4:36a4eceb1b7f 204 return false;
henryrawas 4:36a4eceb1b7f 205 }
henryrawas 4:36a4eceb1b7f 206 else
henryrawas 4:36a4eceb1b7f 207 {
henryrawas 4:36a4eceb1b7f 208 (void)printf("IoTHubClient_SetMessageCallback...successful.\r\n");
henryrawas 4:36a4eceb1b7f 209 }
henryrawas 4:36a4eceb1b7f 210 }
henryrawas 4:36a4eceb1b7f 211 return true;
henryrawas 4:36a4eceb1b7f 212 }
henryrawas 4:36a4eceb1b7f 213
henryrawas 4:36a4eceb1b7f 214 void IothubRobotArm::Terminate()
henryrawas 4:36a4eceb1b7f 215 {
henryrawas 4:36a4eceb1b7f 216 if (iotHubClientHandle != NULL)
henryrawas 4:36a4eceb1b7f 217 {
henryrawas 4:36a4eceb1b7f 218 IoTHubClient_Destroy(iotHubClientHandle);
henryrawas 4:36a4eceb1b7f 219 iotHubClientHandle = NULL;
henryrawas 4:36a4eceb1b7f 220 }
henryrawas 4:36a4eceb1b7f 221 }
henryrawas 4:36a4eceb1b7f 222
henryrawas 4:36a4eceb1b7f 223
henryrawas 4:36a4eceb1b7f 224 void IothubRobotArm::SendMeasurements(void)
henryrawas 4:36a4eceb1b7f 225 {
henryrawas 5:36916b1c5a06 226 // send until circular buf empty or no sending buffers avail
henryrawas 5:36916b1c5a06 227 // may drop message if confirmations are slow
henryrawas 5:36916b1c5a06 228 while (msgNumber - callbackCounter < MESSAGE_COUNT)
henryrawas 5:36916b1c5a06 229 {
henryrawas 5:36916b1c5a06 230 // get buffer from array
henryrawas 5:36916b1c5a06 231 int i = msgNumber % MESSAGE_COUNT;
henryrawas 4:36a4eceb1b7f 232
henryrawas 7:6723f6887d00 233 int msglen = 0;
henryrawas 7:6723f6887d00 234 bool ismeasure = false;
henryrawas 7:6723f6887d00 235 // get alert if any, otherwise get measure data
henryrawas 7:6723f6887d00 236 msglen = msgSerialize.AlertBufToString(msgText, MESSAGE_LEN);
henryrawas 7:6723f6887d00 237 if (msglen == 0)
henryrawas 7:6723f6887d00 238 {
henryrawas 7:6723f6887d00 239 ismeasure = true;
henryrawas 7:6723f6887d00 240 msglen = msgSerialize.MeasureBufToString(msgText, MESSAGE_LEN);
henryrawas 7:6723f6887d00 241 }
henryrawas 7:6723f6887d00 242
henryrawas 4:36a4eceb1b7f 243 if (msglen > 0)
henryrawas 4:36a4eceb1b7f 244 {
henryrawas 4:36a4eceb1b7f 245 if ((messages[i].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, msglen)) == NULL)
henryrawas 4:36a4eceb1b7f 246 {
henryrawas 4:36a4eceb1b7f 247 (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
henryrawas 4:36a4eceb1b7f 248 }
henryrawas 4:36a4eceb1b7f 249 else
henryrawas 4:36a4eceb1b7f 250 {
henryrawas 4:36a4eceb1b7f 251 messages[i].messageTrackingId = msgNumber;
henryrawas 4:36a4eceb1b7f 252
henryrawas 7:6723f6887d00 253 //MAP_HANDLE propMap = IoTHubMessage_Properties(messages[i].messageHandle);
henryrawas 7:6723f6887d00 254 //sprintf_s(propText, sizeof(propText), "PropMsg_%d", msgNumber);
henryrawas 7:6723f6887d00 255 //if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
henryrawas 7:6723f6887d00 256 //{
henryrawas 7:6723f6887d00 257 // (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
henryrawas 7:6723f6887d00 258 //}
henryrawas 4:36a4eceb1b7f 259
henryrawas 4:36a4eceb1b7f 260 if (IoTHubClient_SendEventAsync(iotHubClientHandle, messages[i].messageHandle, SendConfirmationCallback, &messages[i]) != IOTHUB_CLIENT_OK)
henryrawas 4:36a4eceb1b7f 261 {
henryrawas 4:36a4eceb1b7f 262 (void)printf("ERROR: IoTHubClient_SendEventAsync..........FAILED!\r\n");
henryrawas 4:36a4eceb1b7f 263 }
henryrawas 4:36a4eceb1b7f 264 else
henryrawas 4:36a4eceb1b7f 265 {
henryrawas 7:6723f6887d00 266 if (ismeasure)
henryrawas 7:6723f6887d00 267 (void)printf("IoTHubClient_SendEventAsync sending data to IoT Hub. tracking id: %d, bytes: %d\r\n", msgNumber, msglen);
henryrawas 7:6723f6887d00 268 else
henryrawas 7:6723f6887d00 269 (void)printf("IoTHubClient_SendEventAsync sending alert to IoT Hub. tracking id: %d, bytes: %d\r\n", msgNumber, msglen);
henryrawas 4:36a4eceb1b7f 270 }
henryrawas 4:36a4eceb1b7f 271 msgNumber++;
henryrawas 4:36a4eceb1b7f 272 }
henryrawas 4:36a4eceb1b7f 273 }
henryrawas 4:36a4eceb1b7f 274 else if (msglen == 0)
henryrawas 4:36a4eceb1b7f 275 {
henryrawas 4:36a4eceb1b7f 276 break;
henryrawas 4:36a4eceb1b7f 277 }
henryrawas 4:36a4eceb1b7f 278 else if (msglen < 0)
henryrawas 4:36a4eceb1b7f 279 {
henryrawas 4:36a4eceb1b7f 280 (void)printf("ERROR: Serialized message too big for buffer\r\n");
henryrawas 4:36a4eceb1b7f 281 break;
henryrawas 4:36a4eceb1b7f 282 }
henryrawas 4:36a4eceb1b7f 283 } // while
henryrawas 4:36a4eceb1b7f 284
henryrawas 4:36a4eceb1b7f 285 }
henryrawas 7:6723f6887d00 286