/src/mosquitto/lib/will_mosq.c
Line | Count | Source |
1 | | /* |
2 | | Copyright (c) 2010-2021 Roger Light <roger@atchoo.org> |
3 | | |
4 | | All rights reserved. This program and the accompanying materials |
5 | | are made available under the terms of the Eclipse Public License 2.0 |
6 | | and Eclipse Distribution License v1.0 which accompany this distribution. |
7 | | |
8 | | The Eclipse Public License is available at |
9 | | https://www.eclipse.org/legal/epl-2.0/ |
10 | | and the Eclipse Distribution License is available at |
11 | | http://www.eclipse.org/org/documents/edl-v10.php. |
12 | | |
13 | | SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
14 | | |
15 | | Contributors: |
16 | | Roger Light - initial implementation and documentation. |
17 | | */ |
18 | | |
19 | | #include "config.h" |
20 | | |
21 | | #include <stdio.h> |
22 | | #include <string.h> |
23 | | |
24 | | #ifdef WITH_BROKER |
25 | | # include "mosquitto_broker_internal.h" |
26 | | #endif |
27 | | |
28 | | #include "mosquitto.h" |
29 | | #include "mosquitto_internal.h" |
30 | | #include "logging_mosq.h" |
31 | | #include "messages_mosq.h" |
32 | | #include "mosquitto/mqtt_protocol.h" |
33 | | #include "net_mosq.h" |
34 | | #include "read_handle.h" |
35 | | #include "send_mosq.h" |
36 | | #include "util_mosq.h" |
37 | | #include "will_mosq.h" |
38 | | |
39 | | |
40 | | int will__set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties) |
41 | 0 | { |
42 | 0 | int rc = MOSQ_ERR_SUCCESS; |
43 | 0 | mosquitto_property *p; |
44 | |
|
45 | 0 | if(!mosq || !topic){ |
46 | 0 | return MOSQ_ERR_INVAL; |
47 | 0 | } |
48 | 0 | if(payloadlen < 0 || payloadlen > (int)MQTT_MAX_PAYLOAD){ |
49 | 0 | return MOSQ_ERR_PAYLOAD_SIZE; |
50 | 0 | } |
51 | 0 | if(payloadlen > 0 && !payload){ |
52 | 0 | return MOSQ_ERR_INVAL; |
53 | 0 | } |
54 | | |
55 | 0 | if(mosquitto_pub_topic_check(topic)){ |
56 | 0 | return MOSQ_ERR_INVAL; |
57 | 0 | } |
58 | 0 | if(mosquitto_validate_utf8(topic, (uint16_t)strlen(topic))){ |
59 | 0 | return MOSQ_ERR_MALFORMED_UTF8; |
60 | 0 | } |
61 | | |
62 | 0 | if(properties){ |
63 | 0 | if(mosq->protocol != mosq_p_mqtt5){ |
64 | 0 | return MOSQ_ERR_NOT_SUPPORTED; |
65 | 0 | } |
66 | 0 | p = properties; |
67 | 0 | while(p){ |
68 | 0 | rc = mosquitto_property_check_command(CMD_WILL, mosquitto_property_identifier(p)); |
69 | 0 | if(rc){ |
70 | 0 | return rc; |
71 | 0 | } |
72 | 0 | p = mosquitto_property_next(p); |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | 0 | if(mosq->will){ |
77 | 0 | mosquitto_FREE(mosq->will->msg.topic); |
78 | 0 | mosquitto_FREE(mosq->will->msg.payload); |
79 | 0 | mosquitto_property_free_all(&mosq->will->properties); |
80 | 0 | mosquitto_FREE(mosq->will); |
81 | 0 | } |
82 | |
|
83 | 0 | mosq->will = mosquitto_calloc(1, sizeof(struct mosquitto_message_all)); |
84 | 0 | if(!mosq->will){ |
85 | 0 | return MOSQ_ERR_NOMEM; |
86 | 0 | } |
87 | 0 | mosq->will->msg.topic = mosquitto_strdup(topic); |
88 | 0 | if(!mosq->will->msg.topic){ |
89 | 0 | rc = MOSQ_ERR_NOMEM; |
90 | 0 | goto cleanup; |
91 | 0 | } |
92 | 0 | mosq->will->msg.payloadlen = payloadlen; |
93 | 0 | if(mosq->will->msg.payloadlen > 0){ |
94 | 0 | if(!payload){ |
95 | 0 | rc = MOSQ_ERR_INVAL; |
96 | 0 | goto cleanup; |
97 | 0 | } |
98 | 0 | mosq->will->msg.payload = mosquitto_malloc(sizeof(char)*(unsigned int)mosq->will->msg.payloadlen); |
99 | 0 | if(!mosq->will->msg.payload){ |
100 | 0 | rc = MOSQ_ERR_NOMEM; |
101 | 0 | goto cleanup; |
102 | 0 | } |
103 | | |
104 | 0 | memcpy(mosq->will->msg.payload, payload, (unsigned int)payloadlen); |
105 | 0 | } |
106 | 0 | mosq->will->msg.qos = qos; |
107 | 0 | mosq->will->msg.retain = retain; |
108 | |
|
109 | 0 | mosq->will->properties = properties; |
110 | |
|
111 | 0 | return MOSQ_ERR_SUCCESS; |
112 | | |
113 | 0 | cleanup: |
114 | 0 | if(mosq->will){ |
115 | 0 | mosquitto_FREE(mosq->will->msg.topic); |
116 | 0 | mosquitto_FREE(mosq->will->msg.payload); |
117 | 0 | mosquitto_FREE(mosq->will); |
118 | 0 | } |
119 | |
|
120 | 0 | return rc; |
121 | 0 | } |
122 | | |
123 | | |
124 | | int will__clear(struct mosquitto *mosq) |
125 | 0 | { |
126 | 0 | if(!mosq->will){ |
127 | 0 | return MOSQ_ERR_SUCCESS; |
128 | 0 | } |
129 | | |
130 | 0 | mosquitto_FREE(mosq->will->msg.topic); |
131 | 0 | mosquitto_FREE(mosq->will->msg.payload); |
132 | |
|
133 | 0 | mosquitto_property_free_all(&mosq->will->properties); |
134 | |
|
135 | 0 | mosquitto_FREE(mosq->will); |
136 | 0 | mosq->will_delay_interval = 0; |
137 | |
|
138 | 0 | return MOSQ_ERR_SUCCESS; |
139 | 0 | } |
140 | | |