source: azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_message.c@ 457

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

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.0 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 <stdlib.h>
5#include "azure_umqtt_c/mqtt_message.h"
6#include "azure_c_shared_utility/optimize_size.h"
7#include "azure_c_shared_utility/gballoc.h"
8#include "azure_c_shared_utility/xlogging.h"
9#include "azure_c_shared_utility/string_token.h"
10#include "azure_macro_utils/macro_utils.h"
11
12typedef struct MQTT_MESSAGE_TAG
13{
14 uint16_t packetId;
15 QOS_VALUE qosInfo;
16
17 char* topicName;
18 APP_PAYLOAD appPayload;
19
20 const char* const_topic_name;
21 APP_PAYLOAD const_payload;
22
23 bool isDuplicateMsg;
24 bool isMessageRetained;
25} MQTT_MESSAGE;
26
27static MQTT_MESSAGE* create_msg_object(uint16_t packetId, QOS_VALUE qosValue)
28{
29 MQTT_MESSAGE* result;
30 result = (MQTT_MESSAGE*)malloc(sizeof(MQTT_MESSAGE));
31 if (result != NULL)
32 {
33 memset(result, 0, sizeof(MQTT_MESSAGE));
34 result->packetId = packetId;
35 result->isDuplicateMsg = false;
36 result->isMessageRetained = false;
37 result->qosInfo = qosValue;
38 }
39 else
40 {
41 LogError("Failure unable to allocate MQTT Message.");
42 }
43 return result;
44}
45
46MQTT_MESSAGE_HANDLE mqttmessage_create_in_place(uint16_t packetId, const char* topicName, QOS_VALUE qosValue, const uint8_t* appMsg, size_t appMsgLength)
47{
48 /* Codes_SRS_MQTTMESSAGE_07_026: [If the parameters topicName is NULL then mqttmessage_create_in_place shall return NULL.].] */
49 MQTT_MESSAGE* result;
50 if (topicName == NULL)
51 {
52 LogError("Invalid Parameter topicName: %p, packetId: %d.", topicName, packetId);
53 result = NULL;
54 }
55 else
56 {
57 result = create_msg_object(packetId, qosValue);
58 if (result == NULL)
59 {
60 /* Codes_SRS_MQTTMESSAGE_07_028: [If any memory allocation fails mqttmessage_create_in_place shall free any allocated memory and return NULL.] */
61 LogError("Failure creating message object");
62 }
63 else
64 {
65 /* Codes_SRS_MQTTMESSAGE_07_027: [mqttmessage_create_in_place shall use the a pointer to topicName or appMsg .] */
66 result->const_topic_name = topicName;
67 result->const_payload.length = appMsgLength;
68 if (result->const_payload.length > 0)
69 {
70 result->const_payload.message = (uint8_t*)appMsg;
71 }
72 }
73 }
74 /* Codes_SRS_MQTTMESSAGE_07_029: [ Upon success, mqttmessage_create_in_place shall return a NON-NULL MQTT_MESSAGE_HANDLE value.] */
75 return (MQTT_MESSAGE_HANDLE)result;
76}
77
78MQTT_MESSAGE_HANDLE mqttmessage_create(uint16_t packetId, const char* topicName, QOS_VALUE qosValue, const uint8_t* appMsg, size_t appMsgLength)
79{
80 /* Codes_SRS_MQTTMESSAGE_07_001:[If the parameters topicName is NULL is zero then mqttmessage_create shall return NULL.] */
81 MQTT_MESSAGE* result;
82 if (topicName == NULL)
83 {
84 LogError("Invalid Parameter topicName: %p, packetId: %d.", topicName, packetId);
85 result = NULL;
86 }
87 else
88 {
89 /* Codes_SRS_MQTTMESSAGE_07_002: [mqttmessage_create shall allocate and copy the topicName and appMsg parameters.] */
90 result = create_msg_object(packetId, qosValue);
91 if (result == NULL)
92 {
93 /* Codes_SRS_MQTTMESSAGE_07_028: [If any memory allocation fails mqttmessage_create_in_place shall free any allocated memory and return NULL.] */
94 LogError("Failure creating message object");
95 }
96 else
97 {
98 if (mallocAndStrcpy_s(&result->topicName, topicName) != 0)
99 {
100 /* Codes_SRS_MQTTMESSAGE_07_003: [If any memory allocation fails mqttmessage_create shall free any allocated memory and return NULL.] */
101 LogError("Failure allocating topic name");
102 free(result);
103 result = NULL;
104 }
105 else
106 {
107 /* Codes_SRS_MQTTMESSAGE_07_002: [mqttmessage_create shall allocate and copy the topicName and appMsg parameters.] */
108 result->appPayload.length = appMsgLength;
109 if (result->appPayload.length > 0)
110 {
111 result->appPayload.message = malloc(appMsgLength);
112 if (result->appPayload.message == NULL)
113 {
114 /* Codes_SRS_MQTTMESSAGE_07_003: [If any memory allocation fails mqttmessage_create shall free any allocated memory and return NULL.] */
115 LogError("Failure allocating message value of %lu", (unsigned long)appMsgLength);
116 free(result->topicName);
117 free(result);
118 result = NULL;
119 }
120 else
121 {
122 (void)memcpy(result->appPayload.message, appMsg, appMsgLength);
123 }
124 }
125 else
126 {
127 result->appPayload.message = NULL;
128 }
129 }
130 }
131 }
132 /* Codes_SRS_MQTTMESSAGE_07_004: [If mqttmessage_createMessage succeeds the it shall return a NON-NULL MQTT_MESSAGE_HANDLE value.] */
133 return (MQTT_MESSAGE_HANDLE)result;
134}
135
136void mqttmessage_destroy(MQTT_MESSAGE_HANDLE handle)
137{
138 /* Codes_SRS_MQTTMESSAGE_07_005: [If the handle parameter is NULL then mqttmessage_destroyMessage shall do nothing] */
139 if (handle != NULL)
140 {
141 /* Codes_SRS_MQTTMESSAGE_07_006: [mqttmessage_destroyMessage shall free all resources associated with the MQTT_MESSAGE_HANDLE value] */
142 if (handle->topicName != NULL)
143 {
144 free(handle->topicName);
145 }
146 if (handle->appPayload.message != NULL)
147 {
148 free(handle->appPayload.message);
149 }
150 free(handle);
151 }
152}
153
154MQTT_MESSAGE_HANDLE mqttmessage_clone(MQTT_MESSAGE_HANDLE handle)
155{
156 MQTT_MESSAGE_HANDLE result;
157 if (handle == NULL)
158 {
159 /* Codes_SRS_MQTTMESSAGE_07_007: [If handle parameter is NULL then mqttmessage_clone shall return NULL.] */
160 LogError("Invalid Parameter handle: %p.", handle);
161 result = NULL;
162 }
163 else
164 {
165 /* Codes_SRS_MQTTMESSAGE_07_008: [mqttmessage_clone shall create a new MQTT_MESSAGE_HANDLE with data content identical of the handle value.] */
166 result = mqttmessage_create(handle->packetId, handle->topicName, handle->qosInfo, handle->appPayload.message, handle->appPayload.length);
167 if (result != NULL)
168 {
169 result->isDuplicateMsg = handle->isDuplicateMsg;
170 result->isMessageRetained = handle->isMessageRetained;
171 }
172 }
173 return result;
174}
175
176uint16_t mqttmessage_getPacketId(MQTT_MESSAGE_HANDLE handle)
177{
178 uint16_t result;
179 if (handle == NULL)
180 {
181 /* Codes_SRS_MQTTMESSAGE_07_010: [If handle is NULL then mqttmessage_getPacketId shall return 0.] */
182 LogError("Invalid Parameter handle: %p.", handle);
183 result = 0;
184 }
185 else
186 {
187 /* Codes_SRS_MQTTMESSAGE_07_011: [mqttmessage_getPacketId shall return the packetId value contained in MQTT_MESSAGE_HANDLE handle.] */
188 result = handle->packetId;
189 }
190 return result;
191}
192
193const char* mqttmessage_getTopicName(MQTT_MESSAGE_HANDLE handle)
194{
195 const char* result;
196 if (handle == NULL)
197 {
198 /* Codes_SRS_MQTTMESSAGE_07_012: [If handle is NULL then mqttmessage_getTopicName shall return a NULL string.] */
199 LogError("Invalid Parameter handle: %p.", handle);
200 result = NULL;
201 }
202 else
203 {
204 /* Codes_SRS_MQTTMESSAGE_07_013: [mqttmessage_getTopicName shall return the topicName contained in MQTT_MESSAGE_HANDLE handle.] */
205 if (handle->topicName == NULL)
206 {
207 result = handle->const_topic_name;
208 }
209 else
210 {
211 result = handle->topicName;
212 }
213 }
214 return result;
215}
216
217int mqttmessage_getTopicLevels(MQTT_MESSAGE_HANDLE handle, char*** levels, size_t* count)
218{
219 int result;
220
221 // Codes_SRS_MQTTMESSAGE_09_001: [ If `handle`, `levels` or `count` are NULL the function shall return a non-zero value. ]
222 if (handle == NULL || levels == NULL || count == NULL)
223 {
224 LogError("Invalid Parameter handle: %p, levels: %p, count: %p", handle, levels, count);
225 result = MU_FAILURE;
226 }
227 else
228 {
229 MQTT_MESSAGE* msgInfo = (MQTT_MESSAGE*)handle;
230
231 const char* topic_name = msgInfo->topicName != NULL ? msgInfo->topicName : msgInfo->const_topic_name;
232
233 if (topic_name == NULL)
234 {
235 LogError("Topic name is NULL");
236 result = MU_FAILURE;
237 }
238 else
239 {
240 const char* delimiters[1];
241
242 delimiters[0] = "/";
243
244 // Codes_SRS_MQTTMESSAGE_09_002: [ The topic name, excluding the property bag, shall be split into individual tokens using "/" as separator ]
245 // Codes_SRS_MQTTMESSAGE_09_004: [ The split tokens shall be stored in `levels` and its count in `count` ]
246 if (StringToken_Split(topic_name, strlen(topic_name), delimiters, 1, false, levels, count) != 0)
247 {
248 // Codes_SRS_MQTTMESSAGE_09_003: [ If splitting fails the function shall return a non-zero value. ]
249 LogError("Failed splitting topic levels");
250 result = MU_FAILURE;
251 }
252 else
253 {
254 // Codes_SRS_MQTTMESSAGE_09_005: [ If no failures occur the function shall return zero. ]
255 result = 0;
256 }
257 }
258 }
259
260 return result;
261}
262
263QOS_VALUE mqttmessage_getQosType(MQTT_MESSAGE_HANDLE handle)
264{
265 QOS_VALUE result;
266 if (handle == NULL)
267 {
268 /* Codes_SRS_MQTTMESSAGE_07_014: [If handle is NULL then mqttmessage_getQosType shall return the default DELIVER_AT_MOST_ONCE value.] */
269 LogError("Invalid Parameter handle: %p.", handle);
270 result = DELIVER_AT_MOST_ONCE;
271 }
272 else
273 {
274 /* Codes_SRS_MQTTMESSAGE_07_015: [mqttmessage_getQosType shall return the QOS Type value contained in MQTT_MESSAGE_HANDLE handle.] */
275 result = handle->qosInfo;
276 }
277 return result;
278}
279
280bool mqttmessage_getIsDuplicateMsg(MQTT_MESSAGE_HANDLE handle)
281{
282 bool result;
283 if (handle == NULL)
284 {
285 /* Codes_SRS_MQTTMESSAGE_07_016: [If handle is NULL then mqttmessage_getIsDuplicateMsg shall return false.] */
286 LogError("Invalid Parameter handle: %p.", handle);
287 result = false;
288 }
289 else
290 {
291 /* Codes_SRS_MQTTMESSAGE_07_017: [mqttmessage_getIsDuplicateMsg shall return the isDuplicateMsg value contained in MQTT_MESSAGE_HANDLE handle.] */
292 result = handle->isDuplicateMsg;
293 }
294 return result;
295}
296
297bool mqttmessage_getIsRetained(MQTT_MESSAGE_HANDLE handle)
298{
299 bool result;
300 if (handle == NULL)
301 {
302 /* Codes_SRS_MQTTMESSAGE_07_018: [If handle is NULL then mqttmessage_getIsRetained shall return false.] */
303 LogError("Invalid Parameter handle: %p.", handle);
304 result = false;
305 }
306 else
307 {
308 /* Codes_SRS_MQTTMESSAGE_07_019: [mqttmessage_getIsRetained shall return the isRetained value contained in MQTT_MESSAGE_HANDLE handle.] */
309 result = handle->isMessageRetained;
310 }
311 return result;
312}
313
314int mqttmessage_setIsDuplicateMsg(MQTT_MESSAGE_HANDLE handle, bool duplicateMsg)
315{
316 int result;
317 /* Codes_SRS_MQTTMESSAGE_07_022: [If handle is NULL then mqttmessage_setIsDuplicateMsg shall return a non-zero value.] */
318 if (handle == NULL)
319 {
320 LogError("Invalid Parameter handle: %p.", handle);
321 result = MU_FAILURE;
322 }
323 else
324 {
325 /* Codes_SRS_MQTTMESSAGE_07_023: [mqttmessage_setIsDuplicateMsg shall store the duplicateMsg value in the MQTT_MESSAGE_HANDLE handle.] */
326 handle->isDuplicateMsg = duplicateMsg;
327 result = 0;
328 }
329 return result;
330}
331
332int mqttmessage_setIsRetained(MQTT_MESSAGE_HANDLE handle, bool retainMsg)
333{
334 int result;
335 /* Codes_SRS_MQTTMESSAGE_07_024: [If handle is NULL then mqttmessage_setIsRetained shall return a non-zero value.] */
336 if (handle == NULL)
337 {
338 LogError("Invalid Parameter handle: %p.", handle);
339 result = MU_FAILURE;
340 }
341 else
342 {
343 /* Codes_SRS_MQTTMESSAGE_07_025: [mqttmessage_setIsRetained shall store the retainMsg value in the MQTT_MESSAGE_HANDLE handle.] */
344 handle->isMessageRetained = retainMsg;
345 result = 0;
346 }
347 return result;
348}
349
350const APP_PAYLOAD* mqttmessage_getApplicationMsg(MQTT_MESSAGE_HANDLE handle)
351{
352 const APP_PAYLOAD* result;
353 if (handle == NULL)
354 {
355 /* Codes_SRS_MQTTMESSAGE_07_020: [If handle is NULL or if msgLen is 0 then mqttmessage_getApplicationMsg shall return NULL.] */
356 LogError("Invalid Parameter handle: %p.", handle);
357 result = NULL;
358 }
359 else
360 {
361 /* Codes_SRS_MQTTMESSAGE_07_021: [mqttmessage_getApplicationMsg shall return the applicationMsg value contained in MQTT_MESSAGE_HANDLE handle and the length of the appMsg in the msgLen parameter.] */
362 if (handle->const_payload.length > 0)
363 {
364 result = &handle->const_payload;
365 }
366 else
367 {
368 result = &handle->appPayload;
369 }
370 }
371 return result;
372}
Note: See TracBrowser for help on using the repository browser.