source: azure_iot_hub_riscv/trunk/app_iothub_client/src/client.c@ 459

Last change on this file since 459 was 459, checked in by coas-nagasima, 4 years ago

Azure IoT への送信内容を、検出したpersonとcarの数を送信するよう変更。
Azure IoT CentralからLEDのON/OFFが出来るよう更新。

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 16.6 KB
Line 
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4#include <stdio.h>
5#include <stdlib.h>
6
7/* This sample uses the _LL APIs of iothub_client for example purposes.
8That does not mean that HTTP only works with the _LL APIs.
9Simply changing the using the convenience layer (functions not having _LL)
10and removing calls to _DoWork will yield the same results. */
11
12#include "azure_c_shared_utility/threadapi.h"
13#include "azure_c_shared_utility/crt_abstractions.h"
14#include "azure_c_shared_utility/platform.h"
15#include "azure_c_shared_utility/shared_util_options.h"
16#include "iothub_client_ll.h"
17#include "iothub_message.h"
18#include "iothubtransporthttp.h"
19#include "iothubtransportmqtt.h"
20#include "iothubtransportmqtt_websockets.h"
21#include "iothub_client_options.h"
22#include "serializer.h"
23#include "serializer_devicetwin.h"
24#include "client.h"
25#include "kpu_main.h"
26
27#ifdef _MSC_VER
28extern int sprintf_s(char* dst, size_t dstSizeInBytes, const char* format, ...);
29#endif // _MSC_VER
30
31#define SET_TRUSTED_CERT_IN_SAMPLES
32
33#ifdef SET_TRUSTED_CERT_IN_SAMPLES
34#include "certs.h"
35#endif // SET_TRUSTED_CERT_IN_SAMPLES
36
37/*String containing Hostname, Device Id & Device Key in the format: */
38/* "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>" */
39/* "HostName=<host_name>;DeviceId=<device_id>;SharedAccessSignature=<device_sas_token>" */
40char* connectionString = NULL;
41
42bool g_use_proxy;
43HTTP_PROXY_OPTIONS g_proxy_options;
44
45static int callbackCounter;
46static bool g_continueRunning;
47static bool g_twinReport;
48static char propText[1024];
49#define MESSAGE_COUNT 5
50#define DOWORK_LOOP_NUM 3
51
52typedef struct EVENT_INSTANCE_TAG
53{
54 IOTHUB_MESSAGE_HANDLE messageHandle;
55 size_t messageTrackingId; // For tracking the messages within the user callback.
56} EVENT_INSTANCE;
57
58static IOTHUBMESSAGE_DISPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
59{
60 int* counter = (int*)userContextCallback;
61 const char* buffer;
62 size_t size;
63 MAP_HANDLE mapProperties;
64 const char* messageId;
65 const char* correlationId;
66 const char* contentType;
67 const char* contentEncoding;
68
69 // Message properties
70 if ((messageId = IoTHubMessage_GetMessageId(message)) == NULL)
71 {
72 messageId = "<null>";
73 }
74
75 if ((correlationId = IoTHubMessage_GetCorrelationId(message)) == NULL)
76 {
77 correlationId = "<null>";
78 }
79
80 if ((contentType = IoTHubMessage_GetContentTypeSystemProperty(message)) == NULL)
81 {
82 contentType = "<null>";
83 }
84
85 if ((contentEncoding = IoTHubMessage_GetContentEncodingSystemProperty(message)) == NULL)
86 {
87 contentEncoding = "<null>";
88 }
89
90 // Message content
91 if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) != IOTHUB_MESSAGE_OK)
92 {
93 printf("unable to retrieve the message data\r\n");
94 }
95 else
96 {
97 (void)printf("Received Message [%d]\r\n Message ID: %s\r\n Correlation ID: %s\r\n Content-Type: %s\r\n Content-Encoding: %s\r\n Data: <<<%.*s>>> & Size=%d\r\n",
98 *counter, messageId, correlationId, contentType, contentEncoding, (int)size, buffer, (int)size);
99 // If we receive the work 'quit' then we stop running
100 if (size == (strlen("quit") * sizeof(char)) && memcmp(buffer, "quit", size) == 0)
101 {
102 g_continueRunning = false;
103 }
104 }
105
106 // Retrieve properties from the message
107 mapProperties = IoTHubMessage_Properties(message);
108 if (mapProperties != NULL)
109 {
110 const char*const* keys;
111 const char*const* values;
112 size_t propertyCount = 0;
113 if (Map_GetInternals(mapProperties, &keys, &values, &propertyCount) == MAP_OK)
114 {
115 if (propertyCount > 0)
116 {
117 size_t index;
118
119 printf(" Message Properties:\r\n");
120 for (index = 0; index < propertyCount; index++)
121 {
122 (void)printf("\tKey: %s Value: %s\r\n", keys[index], values[index]);
123 }
124 (void)printf("\r\n");
125 }
126 }
127 }
128
129 /* Some device specific action code goes here... */
130 (*counter)++;
131 return IOTHUBMESSAGE_ACCEPTED;
132}
133
134// Define the Model
135BEGIN_NAMESPACE(SecurityStation);
136
137DECLARE_MODEL(ContosoSecurityCamera,
138WITH_DATA(int, is_person),
139WITH_DATA(int, is_car),
140WITH_METHOD(quit),
141WITH_METHOD(turnLedOn),
142WITH_METHOD(turnLedOff)
143);
144
145DECLARE_STRUCT(ThresholdD,
146 double, value
147);
148
149DECLARE_STRUCT(ThresholdR,
150 double, value,
151 ascii_char_ptr, status
152);
153
154DECLARE_DEVICETWIN_MODEL(SecurityCameraState,
155WITH_REPORTED_PROPERTY(ThresholdR, threshold)
156);
157
158DECLARE_DEVICETWIN_MODEL(SecurityCameraSettings,
159WITH_DESIRED_PROPERTY(ThresholdD, threshold, onDesiredThreshold)
160);
161
162END_NAMESPACE(SecurityStation);
163
164void anemometerReportedStateCallback(int status_code, void* userContextCallback)
165{
166 SecurityCameraState *anemometer = (SecurityCameraState *)userContextCallback;
167
168 printf("received states \033[43m%d\033[49m, reported threshold = %.1f\n", status_code, anemometer->threshold.value);
169}
170
171void onDesiredThreshold(void* argument)
172{
173 // Note: The argument is NOT a pointer to threshold, but instead a pointer to the MODEL
174 // that contains threshold as one of its arguments. In this case, it
175 // is SecurityCameraSettings*.
176
177 SecurityCameraSettings *anemometer = (SecurityCameraSettings *)argument;
178 printf("received a new desired.threshold = \033[42m%.1f\033[49m\n", anemometer->threshold.value);
179
180 g_twinReport = true;
181}
182
183METHODRETURN_HANDLE quit(ContosoSecurityCamera* device)
184{
185 (void)device;
186 (void)printf("quit with Method.\r\n");
187
188 g_continueRunning = false;
189
190 METHODRETURN_HANDLE result = MethodReturn_Create(0, "{\"Message\":\"quit with Method\"}");
191 return result;
192}
193
194METHODRETURN_HANDLE turnLedOn(ContosoSecurityCamera* device)
195{
196 (void)device;
197 (void)printf("\033[41mTurning LED on with Method.\033[49m\r\n");
198
199 digitalWrite(LED_G_PIN, LOW);
200 digitalWrite(LED_R_PIN, LOW);
201 digitalWrite(LED_B_PIN, LOW);
202
203 METHODRETURN_HANDLE result = MethodReturn_Create(1, "{\"Message\":\"Turning fan on with Method\"}");
204 return result;
205}
206
207METHODRETURN_HANDLE turnLedOff(ContosoSecurityCamera* device)
208{
209 (void)device;
210 (void)printf("\033[44mTurning LED off with Method.\033[49m\r\n");
211
212 digitalWrite(LED_G_PIN, HIGH);
213 digitalWrite(LED_R_PIN, HIGH);
214 digitalWrite(LED_B_PIN, HIGH);
215
216 METHODRETURN_HANDLE result = MethodReturn_Create(0, "{\"Message\":\"Turning fan off with Method\"}");
217 return result;
218}
219
220static int ReceiveDeviceMethodCallback(const char* method_name, const unsigned char* payload, size_t size, unsigned char** response, size_t* resp_size, void* userContextCallback)
221{
222 int result;
223
224 /*this is step 3: receive the method and push that payload into serializer (from below)*/
225 char* payloadZeroTerminated = (char*)malloc(size + 1);
226 if (payloadZeroTerminated == 0)
227 {
228 printf("failed to malloc\r\n");
229 *resp_size = 0;
230 *response = NULL;
231 result = -1;
232 }
233 else
234 {
235 (void)memcpy(payloadZeroTerminated, payload, size);
236 payloadZeroTerminated[size] = '\0';
237
238 /*execute method - userContextCallback is of type deviceModel*/
239 METHODRETURN_HANDLE methodResult = EXECUTE_METHOD(userContextCallback, method_name, payloadZeroTerminated);
240 free(payloadZeroTerminated);
241
242 if (methodResult == NULL)
243 {
244 printf("failed to EXECUTE_METHOD\r\n");
245 *resp_size = 0;
246 *response = NULL;
247 result = -1;
248 }
249 else
250 {
251 /* get the serializer answer and push it in the networking stack*/
252 const METHODRETURN_DATA* data = MethodReturn_GetReturn(methodResult);
253 if (data == NULL)
254 {
255 printf("failed to MethodReturn_GetReturn\r\n");
256 *resp_size = 0;
257 *response = NULL;
258 result = -1;
259 }
260 else
261 {
262 result = data->statusCode;
263 if (data->jsonValue == NULL)
264 {
265 char* resp = "{}";
266 *resp_size = strlen(resp);
267 *response = (unsigned char*)malloc(*resp_size);
268 (void)memcpy(*response, resp, *resp_size);
269 }
270 else
271 {
272 *resp_size = strlen(data->jsonValue);
273 *response = (unsigned char*)malloc(*resp_size);
274 (void)memcpy(*response, data->jsonValue, *resp_size);
275 }
276 }
277 MethodReturn_Destroy(methodResult);
278 }
279 }
280 return result;
281}
282
283static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
284{
285 EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
286
287 (void)printf("Confirmation[%d] received for message tracking id = %u with result = %s\r\n", callbackCounter, eventInstance->messageTrackingId, MU_ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
288
289 /* Some device specific action code goes here... */
290 callbackCounter++;
291 IoTHubMessage_Destroy(eventInstance->messageHandle);
292}
293
294void iothub_client_run(int proto)
295{
296 IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle;
297
298 EVENT_INSTANCE messages[MESSAGE_COUNT];
299 int msg_id = 0;
300 int receiveContext = 0;
301
302 g_continueRunning = true;
303
304 srand((unsigned int)time(NULL));
305
306 callbackCounter = 0;
307
308 if (platform_init() != 0)
309 {
310 (void)printf("Failed to initialize the platform.\r\n");
311 }
312 else {
313 if (serializer_init(NULL) != SERIALIZER_OK)
314 {
315 (void)printf("Failed in serializer_init.");
316 }
317 else if (SERIALIZER_REGISTER_NAMESPACE(SecurityStation) == NULL)
318 {
319 LogError("unable to SERIALIZER_REGISTER_NAMESPACE");
320 }
321 else
322 {
323 IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol;
324 switch (proto) {
325 case 0:
326 (void)printf("Starting the IoTHub client sample HTTP...\r\n");
327 protocol = HTTP_Protocol;
328 break;
329 case 1:
330 (void)printf("Starting the IoTHub client sample MQTT...\r\n");
331 protocol = MQTT_Protocol;
332 break;
333 case 2:
334 (void)printf("Starting the IoTHub client sample MQTT over WebSocket...\r\n");
335 protocol = MQTT_WebSocket_Protocol;
336 break;
337 default:
338 platform_deinit();
339 return;
340 }
341
342 if ((iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, protocol)) == NULL)
343 {
344 (void)printf("ERROR: iotHubClientHandle is NULL!\r\n");
345 }
346 else
347 {
348 if (g_use_proxy)
349 {
350 if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_HTTP_PROXY, &g_proxy_options) != IOTHUB_CLIENT_OK)
351 {
352 printf("failure to set option \"HTTP Proxy\"\r\n");
353 }
354 }
355#if 0
356 long curl_verbose = 1;
357 if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_CURL_VERBOSE, &curl_verbose) != IOTHUB_CLIENT_OK)
358 {
359 printf("failure to set option \"CURL Verbose\"\r\n");
360 }
361
362 unsigned int timeout = 241000;
363 // Because it can poll "after 9 seconds" polls will happen effectively // at ~10 seconds.
364 // Note that for scalabilty, the default value of minimumPollingTime
365 // is 25 minutes. For more information, see:
366 // https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
367 unsigned int minimumPollingTime = 9;
368 if (IoTHubClient_LL_SetOption(iotHubClientHandle, "timeout", &timeout) != IOTHUB_CLIENT_OK)
369 {
370 printf("failure to set option \"timeout\"\r\n");
371 }
372
373 if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
374 {
375 printf("failure to set option \"MinimumPollingTime\"\r\n");
376 }
377
378 bool traceOn = 1;
379 if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_LOG_TRACE, &traceOn) != IOTHUB_CLIENT_OK)
380 {
381 printf("failure to set option \"log trace on\"\r\n");
382 }
383#endif
384#ifdef SET_TRUSTED_CERT_IN_SAMPLES
385 // For mbed add the certificate information
386 if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_TRUSTED_CERT, certificates) != IOTHUB_CLIENT_OK)
387 {
388 printf("failure to set option \"TrustedCerts\"\r\n");
389 }
390#endif // SET_TRUSTED_CERT_IN_SAMPLES
391 SecurityCameraState *anemometerState = IoTHubDeviceTwin_LL_CreateSecurityCameraState(iotHubClientHandle);
392 if (anemometerState == NULL)
393 {
394 printf("Failure in IoTHubDeviceTwin_LL_CreateSecurityCameraState");
395 }
396 else
397 {
398 (void)printf("IoTHubDeviceTwin_LL_CreateSecurityCameraState...successful.\r\n");
399 }
400 SecurityCameraSettings *anemometerSettings = IoTHubDeviceTwin_LL_CreateSecurityCameraSettings(iotHubClientHandle);
401 if (anemometerSettings == NULL)
402 {
403 printf("Failure in IoTHubDeviceTwin_LL_CreateSecurityCameraSettings");
404 }
405 else
406 {
407 (void)printf("IoTHubDeviceTwin_LL_CreateSecurityCameraSettings...successful.\r\n");
408 }
409 ContosoSecurityCamera* myWeather = CREATE_MODEL_INSTANCE(SecurityStation, ContosoSecurityCamera);
410 if (myWeather == NULL)
411 {
412 (void)printf("Failed on CREATE_MODEL_INSTANCE\r\n");
413 }
414 else if (IoTHubClient_LL_SetDeviceMethodCallback(iotHubClientHandle, ReceiveDeviceMethodCallback, myWeather) != IOTHUB_CLIENT_OK)
415 {
416 (void)printf("ERROR: IoTHubClient_LL_SetDeviceMethodCallback..........FAILED!\r\n");
417 }
418 else
419 {
420 (void)printf("IoTHubClient_LL_SetDeviceMethodCallback...successful.\r\n");
421 }
422 /* Setting Message call back, so we can receive Commands. */
423 if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, ReceiveMessageCallback, &receiveContext) != IOTHUB_CLIENT_OK)
424 {
425 (void)printf("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n");
426 }
427 else
428 {
429 (void)printf("IoTHubClient_LL_SetMessageCallback...successful.\r\n");
430 }
431
432 /* Now that we are ready to receive commands, let's send some messages */
433 int iterator = 4000;
434 do
435 {
436 if (iterator >= 5000)
437 {
438 iterator = 0;
439 int msgPos = msg_id % MESSAGE_COUNT;
440 unsigned char *msgText;
441 size_t msgSize;
442 myWeather->is_person = yolo_result.person;
443 myWeather->is_car = yolo_result.car;
444 yolo_result.reset = 1;
445 if (SERIALIZE(&msgText, &msgSize, myWeather->is_person, myWeather->is_car) != CODEFIRST_OK)
446 {
447 (void)printf("Failed to serialize\r\n");
448 }
449 else if ((messages[msgPos].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, msgSize)) == NULL)
450 {
451 (void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
452 free(msgText);
453 }
454 else
455 {
456 MAP_HANDLE propMap;
457
458 messages[msgPos].messageTrackingId = msg_id;
459
460 propMap = IoTHubMessage_Properties(messages[msgPos].messageHandle);
461 (void)sprintf_s(propText, sizeof(propText), (yolo_result.person > 0) ? "true" : "false");
462 if (Map_AddOrUpdate(propMap, "personAlert", propText) != MAP_OK)
463 {
464 (void)printf("ERROR: Map_AddOrUpdate Failed!\r\n");
465 }
466
467 if (proto == 0) {
468 (void)IoTHubMessage_SetContentTypeSystemProperty(messages[msgPos].messageHandle, "application/json");
469 (void)IoTHubMessage_SetContentEncodingSystemProperty(messages[msgPos].messageHandle, "utf-8");
470 }
471
472 if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[msgPos].messageHandle, SendConfirmationCallback, &messages[msgPos]) != IOTHUB_CLIENT_OK)
473 {
474 (void)printf("ERROR: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
475 }
476 else
477 {
478 (void)printf("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT Hub.\r\n", msg_id);
479 }
480
481 free(msgText);
482 msg_id++;
483 }
484 }
485 else if (g_twinReport) {
486 g_twinReport = false;
487 anemometerState->threshold.value = anemometerSettings->threshold.value;
488 anemometerState->threshold.status = "success";
489 IoTHubDeviceTwin_LL_SendReportedStateSecurityCameraState(anemometerState, anemometerReportedStateCallback, anemometerState);
490 }
491 iterator++;
492
493 IoTHubClient_LL_DoWork(iotHubClientHandle);
494 ThreadAPI_Sleep(1);
495
496 } while (g_continueRunning);
497
498 (void)printf("iothub_client_run has gotten quit message, call DoWork %d more time to complete final sending...\r\n", DOWORK_LOOP_NUM);
499 for (size_t index = 0; index < DOWORK_LOOP_NUM; index++)
500 {
501 IoTHubClient_LL_DoWork(iotHubClientHandle);
502 ThreadAPI_Sleep(1);
503 }
504
505 if (anemometerSettings != NULL)
506 IoTHubDeviceTwin_LL_DestroySecurityCameraSettings(anemometerSettings);
507 if (anemometerState != NULL)
508 IoTHubDeviceTwin_LL_DestroySecurityCameraState(anemometerState);
509 if (myWeather != NULL)
510 DESTROY_MODEL_INSTANCE(myWeather);
511 IoTHubClient_LL_Destroy(iotHubClientHandle);
512 }
513 serializer_deinit();
514 }
515 platform_deinit();
516 }
517}
518
519void iothub_client_init()
520{
521#if 0
522 char *set_cs_argv[2] = {
523 "set_cs",
524 "[device connection string]"
525 };
526 set_cs_main(2, set_cs_argv);
527
528 char *set_proxy_argv[2] = {
529 "set_proxy",
530 "example.com:8080"
531 };
532 set_proxy_main(2, set_proxy_argv);
533#endif
534}
535
536int iothub_client_main(int argc, char **argv)
537{
538 if (connectionString == NULL) {
539 printf("Not set connection string, use 'device csgen' or 'device setcs'.\n");
540 return 0;
541 }
542
543 if (argc < 2) {
544 iothub_client_run(1);
545 return 0;
546 }
547
548 if (strcmp(argv[1], "http") == 0) {
549 iothub_client_run(0);
550 return 0;
551 }
552 else if (strcmp(argv[1], "mqtt") == 0) {
553 iothub_client_run(1);
554 return 0;
555 }
556 else if (strcmp(argv[1], "mqttows") == 0) {
557 iothub_client_run(2);
558 return 0;
559 }
560
561 printf("%s [http|mqtt|mqttows] \n", argv[0]);
562 return 0;
563}
Note: See TracBrowser for help on using the repository browser.