Low level MQTTSN packet library, part of the Eclipse Paho project: http://eclipse.org/paho
Dependents: MQTTSN sara-n200-hello-mqtt-sn MQTTSN_2
MQTTSNConnectClient.c
00001 /******************************************************************************* 00002 * Copyright (c) 2014, 2015 IBM Corp. 00003 * 00004 * All rights reserved. This program and the accompanying materials 00005 * are made available under the terms of the Eclipse Public License v1.0 00006 * and Eclipse Distribution License v1.0 which accompany this distribution. 00007 * 00008 * The Eclipse Public License is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * and the Eclipse Distribution License is available at 00011 * http://www.eclipse.org/org/documents/edl-v10.php. 00012 * 00013 * Contributors: 00014 * Ian Craggs - initial API and implementation and/or initial documentation 00015 * Nicholas Humfrey - Reformatting to make more consistent; bug 453862 00016 *******************************************************************************/ 00017 00018 #include "MQTTSNPacket.h" 00019 #include "StackTrace.h" 00020 00021 #include <string.h> 00022 00023 /** 00024 * Determines the length of the MQTT connect packet that would be produced using the supplied connect options. 00025 * @param options the options to be used to build the connect packet 00026 * @return the length of buffer needed to contain the serialized version of the packet 00027 */ 00028 int MQTTSNSerialize_connectLength(MQTTSNPacket_connectData* options) 00029 { 00030 int len = 0; 00031 00032 FUNC_ENTRY; 00033 len = 5 + MQTTSNstrlen(options->clientID); 00034 FUNC_EXIT_RC(len); 00035 return len; 00036 } 00037 00038 00039 /** 00040 * Serializes the connect options into the buffer. 00041 * @param buf the buffer into which the packet will be serialized 00042 * @param len the length in bytes of the supplied buffer 00043 * @param options the options to be used to build the connect packet 00044 * @return serialized length, or error if 0 00045 */ 00046 int MQTTSNSerialize_connect(unsigned char* buf, int buflen, MQTTSNPacket_connectData* options) 00047 { 00048 unsigned char *ptr = buf; 00049 MQTTSNFlags flags = {0}; 00050 int len = 0; 00051 int rc = -1; 00052 00053 FUNC_ENTRY; 00054 if ((len = MQTTSNPacket_len(MQTTSNSerialize_connectLength(options))) > buflen) 00055 { 00056 rc = MQTTSNPACKET_BUFFER_TOO_SHORT; 00057 goto exit; 00058 } 00059 ptr += MQTTSNPacket_encode(ptr, len); /* write length */ 00060 MQTTSNPacket_writeChar(&ptr, MQTTSN_CONNECT); /* write message type */ 00061 00062 flags.all = 0; 00063 flags.bits.cleanSession = options->cleansession; 00064 flags.bits.will = options->willFlag; 00065 MQTTSNPacket_writeChar(&ptr, flags.all); 00066 MQTTSNPacket_writeChar(&ptr, 0x01); /* protocol ID */ 00067 MQTTSNPacket_writeInt(&ptr, options->duration); 00068 writeMQTTSNString(&ptr, options->clientID); 00069 00070 rc = ptr - buf; 00071 exit: 00072 FUNC_EXIT_RC(rc); 00073 return rc; 00074 } 00075 00076 00077 /** 00078 * Deserializes the supplied (wire) buffer into connack data - return code 00079 * @param connack_rc returned integer value of the connack return code 00080 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00081 * @param len the length in bytes of the data in the supplied buffer 00082 * @return error code. 1 is success, 0 is failure 00083 */ 00084 int MQTTSNDeserialize_connack(int* connack_rc, unsigned char* buf, int buflen) 00085 { 00086 unsigned char* curdata = buf; 00087 unsigned char* enddata = NULL; 00088 int rc = 0; 00089 int mylen; 00090 00091 FUNC_ENTRY; 00092 curdata += (rc = MQTTSNPacket_decode(curdata, buflen, &mylen)); /* read length */ 00093 enddata = buf + mylen; 00094 if (enddata - buf < 3) 00095 goto exit; 00096 00097 if (MQTTSNPacket_readChar(&curdata) != MQTTSN_CONNACK) 00098 goto exit; 00099 00100 *connack_rc = MQTTSNPacket_readChar(&curdata); 00101 00102 rc = 1; 00103 exit: 00104 FUNC_EXIT_RC(rc); 00105 return rc; 00106 } 00107 00108 00109 /** 00110 * Determines the length of the MQTT disconnect packet (without length field) 00111 * @param duration the parameter used for the disconnect 00112 * @return the length of buffer needed to contain the serialized version of the packet 00113 */ 00114 int MQTTSNSerialize_disconnectLength(int duration) 00115 { 00116 int len = 0; 00117 00118 FUNC_ENTRY; 00119 len = (duration >= 0) ? 3 : 1; 00120 FUNC_EXIT_RC(len); 00121 return len; 00122 } 00123 00124 00125 /** 00126 * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 00127 * @param buf the buffer into which the packet will be serialized 00128 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00129 * @param duration optional duration, not added to packet if < 0 00130 * @return serialized length, or error if 0 00131 */ 00132 int MQTTSNSerialize_disconnect(unsigned char* buf, int buflen, int duration) 00133 { 00134 int rc = -1; 00135 unsigned char *ptr = buf; 00136 int len = 0; 00137 00138 FUNC_ENTRY; 00139 if ((len = MQTTSNPacket_len(MQTTSNSerialize_disconnectLength(duration))) > buflen) 00140 { 00141 rc = MQTTSNPACKET_BUFFER_TOO_SHORT; 00142 goto exit; 00143 } 00144 ptr += MQTTSNPacket_encode(ptr, len); /* write length */ 00145 MQTTSNPacket_writeChar(&ptr, MQTTSN_DISCONNECT); /* write message type */ 00146 00147 if (duration >= 0) 00148 MQTTSNPacket_writeInt(&ptr, duration); 00149 00150 rc = ptr - buf; 00151 exit: 00152 FUNC_EXIT_RC(rc); 00153 return rc; 00154 } 00155 00156 00157 /** 00158 * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 00159 * @param buf the buffer into which the packet will be serialized 00160 * @param buflen the length in bytes of the supplied buffer, to avoid overruns 00161 * @param clientid optional string, not added to packet string == NULL 00162 * @return serialized length, or error if 0 00163 */ 00164 int MQTTSNSerialize_pingreq(unsigned char* buf, int buflen, MQTTSNString clientid) 00165 { 00166 int rc = -1; 00167 unsigned char *ptr = buf; 00168 int len = 0; 00169 00170 FUNC_ENTRY; 00171 if ((len = MQTTSNPacket_len(MQTTSNstrlen(clientid) + 1)) > buflen) 00172 { 00173 rc = MQTTSNPACKET_BUFFER_TOO_SHORT; 00174 goto exit; 00175 } 00176 ptr += MQTTSNPacket_encode(ptr, len); /* write length */ 00177 MQTTSNPacket_writeChar(&ptr, MQTTSN_PINGREQ); /* write message type */ 00178 00179 writeMQTTSNString(&ptr, clientid); 00180 00181 rc = ptr - buf; 00182 exit: 00183 FUNC_EXIT_RC(rc); 00184 return rc; 00185 } 00186 00187 00188 /** 00189 * Deserializes the supplied (wire) buffer 00190 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00191 * @param len the length in bytes of the data in the supplied buffer 00192 * @return error code. 1 is success, 0 is failure 00193 */ 00194 int MQTTSNDeserialize_pingresp(unsigned char* buf, int buflen) 00195 { 00196 unsigned char* curdata = buf; 00197 unsigned char* enddata = NULL; 00198 int rc = 0; 00199 int mylen; 00200 00201 FUNC_ENTRY; 00202 curdata += (rc = MQTTSNPacket_decode(curdata, buflen, &mylen)); /* read length */ 00203 enddata = buf + mylen; 00204 if (enddata - curdata < 2) 00205 goto exit; 00206 00207 if (MQTTSNPacket_readChar(&curdata) != MQTTSN_PINGRESP) 00208 goto exit; 00209 00210 rc = 1; 00211 exit: 00212 FUNC_EXIT_RC(rc); 00213 return rc; 00214 } 00215 00216 00217 /** 00218 * Serializes a willtopic or willtopicupd packet into the supplied buffer. 00219 * @param buf the buffer into which the packet will be serialized 00220 * @param len the length in bytes of the supplied buffer 00221 * @param willQoS the qos of the will message 00222 * @param willRetain the retained flag of the will message 00223 * @param willTopic the topic of the will message 00224 * @return serialized length, or error if 0 00225 */ 00226 int MQTTSNSerialize_willtopic1(unsigned char* buf, int buflen, int willQoS, unsigned char willRetain, MQTTSNString willTopic, 00227 enum MQTTSN_msgTypes packet_type) 00228 { 00229 unsigned char *ptr = buf; 00230 MQTTSNFlags flags = {0}; 00231 int len = 0; 00232 int rc = -1; 00233 00234 FUNC_ENTRY; 00235 if ((len = MQTTSNPacket_len(MQTTSNstrlen(willTopic) + 2)) > buflen) 00236 { 00237 rc = MQTTSNPACKET_BUFFER_TOO_SHORT; 00238 goto exit; 00239 } 00240 ptr += MQTTSNPacket_encode(ptr, len); /* write length */ 00241 MQTTSNPacket_writeChar(&ptr, packet_type); /* write message type */ 00242 00243 flags.all = 0; 00244 flags.bits.QoS = willQoS; 00245 flags.bits.retain = willRetain; 00246 MQTTSNPacket_writeChar(&ptr, flags.all); 00247 00248 writeMQTTSNString(&ptr, willTopic); 00249 00250 rc = ptr - buf; 00251 00252 exit: 00253 FUNC_EXIT_RC(rc); 00254 return rc; 00255 } 00256 00257 00258 /** 00259 * Serializes a willtopicupd packet into the supplied buffer. 00260 * @param buf the buffer into which the packet will be serialized 00261 * @param len the length in bytes of the supplied buffer 00262 * @param willQoS the qos of the will message 00263 * @param willRetain the retained flag of the will message 00264 * @param willTopic the topic of the will message 00265 * @return serialized length, or error if 0 00266 */ 00267 int MQTTSNSerialize_willtopicupd(unsigned char* buf, int buflen, int willQoS, unsigned char willRetain, MQTTSNString willTopic) 00268 { 00269 return MQTTSNSerialize_willtopic1(buf, buflen, willQoS, willRetain, willTopic, MQTTSN_WILLTOPICUPD); 00270 } 00271 00272 00273 /** 00274 * Serializes a willtopic packet into the supplied buffer. 00275 * @param buf the buffer into which the packet will be serialized 00276 * @param len the length in bytes of the supplied buffer 00277 * @param willQoS the qos of the will message 00278 * @param willRetain the retained flag of the will message 00279 * @param willTopic the topic of the will message 00280 * @return serialized length, or error if 0 00281 */ 00282 int MQTTSNSerialize_willtopic(unsigned char* buf, int buflen, int willQoS, unsigned char willRetain, MQTTSNString willTopic) 00283 { 00284 return MQTTSNSerialize_willtopic1(buf, buflen, willQoS, willRetain, willTopic, MQTTSN_WILLTOPIC); 00285 } 00286 00287 00288 /** 00289 * Serializes a willmsg or willmsgupd packet into the supplied buffer. 00290 * @param buf the buffer into which the packet will be serialized 00291 * @param buflen the length in bytes of the supplied buffer 00292 * @param willMsg the will message 00293 * @return serialized length, or error if 0 00294 */ 00295 int MQTTSNSerialize_willmsg1(unsigned char* buf, int buflen, MQTTSNString willMsg, enum MQTTSN_msgTypes packet_type) 00296 { 00297 unsigned char *ptr = buf; 00298 int len = 0; 00299 int rc = -1; 00300 00301 FUNC_ENTRY; 00302 if ((len = MQTTSNPacket_len(MQTTSNstrlen(willMsg) + 1)) > buflen) 00303 { 00304 rc = MQTTSNPACKET_BUFFER_TOO_SHORT; 00305 goto exit; 00306 } 00307 ptr += MQTTSNPacket_encode(ptr, len); /* write length */ 00308 MQTTSNPacket_writeChar(&ptr, packet_type); /* write message type */ 00309 00310 writeMQTTSNString(&ptr, willMsg); 00311 00312 rc = ptr - buf; 00313 exit: 00314 FUNC_EXIT_RC(rc); 00315 return rc; 00316 } 00317 00318 00319 /** 00320 * Serializes a willmsg packet into the supplied buffer. 00321 * @param buf the buffer into which the packet will be serialized 00322 * @param len the length in bytes of the supplied buffersage 00323 * @param willMsg the will message 00324 * @return serialized length, or error if 0 00325 */ 00326 int MQTTSNSerialize_willmsg(unsigned char* buf, int buflen, MQTTSNString willMsg) 00327 { 00328 return MQTTSNSerialize_willmsg1(buf, buflen, willMsg, MQTTSN_WILLMSG); 00329 } 00330 00331 00332 /** 00333 * Serializes a willmsgupd packet into the supplied buffer. 00334 * @param buf the buffer into which the packet will be serialized 00335 * @param len the length in bytes of the supplied buffersage 00336 * @param willMsg the will message 00337 * @return serialized length, or error if 0 00338 */ 00339 int MQTTSNSerialize_willmsgupd(unsigned char* buf, int buflen, MQTTSNString willMsg) 00340 { 00341 return MQTTSNSerialize_willmsg1(buf, buflen, willMsg, MQTTSN_WILLMSGUPD); 00342 } 00343 00344 00345 /** 00346 * Deserializes the supplied (wire) buffer 00347 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00348 * @param len the length in bytes of the data in the supplied buffer 00349 * @return error code. 1 is success, 0 is failure 00350 */ 00351 int MQTTSNDeserialize_willtopicreq(unsigned char* buf, int buflen) 00352 { 00353 unsigned char* curdata = buf; 00354 unsigned char* enddata = NULL; 00355 int rc = -1; 00356 int mylen; 00357 00358 FUNC_ENTRY; 00359 if (MQTTSNPacket_decode(curdata++, buflen, &mylen) != 1) /* read length */ 00360 goto exit; 00361 if (mylen > buflen) 00362 { 00363 rc = MQTTSNPACKET_BUFFER_TOO_SHORT; 00364 goto exit; 00365 } 00366 enddata = buf + mylen; 00367 if (enddata - curdata < 1) 00368 goto exit; 00369 00370 if (MQTTSNPacket_readChar(&curdata) != MQTTSN_WILLTOPICREQ) 00371 goto exit; 00372 00373 rc = 1; 00374 exit: 00375 FUNC_EXIT_RC(rc); 00376 return rc; 00377 } 00378 00379 00380 /** 00381 * Deserializes the supplied (wire) buffer 00382 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00383 * @param len the length in bytes of the data in the supplied buffer 00384 * @return error code. 1 is success, 0 is failure 00385 */ 00386 int MQTTSNDeserialize_willmsgreq(unsigned char* buf, int buflen) 00387 { 00388 unsigned char* curdata = buf; 00389 unsigned char* enddata = NULL; 00390 int rc = -1; 00391 int mylen; 00392 00393 FUNC_ENTRY; 00394 if (MQTTSNPacket_decode(curdata++, buflen, &mylen) != 1) /* read length */ 00395 goto exit; 00396 if (mylen > buflen) 00397 { 00398 rc = MQTTSNPACKET_BUFFER_TOO_SHORT; 00399 goto exit; 00400 } 00401 enddata = buf + mylen; 00402 if (enddata - curdata < 1) 00403 goto exit; 00404 00405 if (MQTTSNPacket_readChar(&curdata) != MQTTSN_WILLMSGREQ) 00406 goto exit; 00407 00408 rc = 1; 00409 exit: 00410 FUNC_EXIT_RC(rc); 00411 return rc; 00412 } 00413 00414 00415 /** 00416 * Deserializes the supplied (wire) buffer into willtopicresp data - return code 00417 * @param connack_rc returned integer value of the return code 00418 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00419 * @param len the length in bytes of the data in the supplied buffer 00420 * @return error code. 1 is success, 0 is failure 00421 */ 00422 int MQTTSNDeserialize_willtopicresp(int* resp_rc, unsigned char* buf, int buflen) 00423 { 00424 unsigned char* curdata = buf; 00425 unsigned char* enddata = NULL; 00426 int rc = 0; 00427 int mylen; 00428 00429 FUNC_ENTRY; 00430 curdata += (rc = MQTTSNPacket_decode(curdata, buflen, &mylen)); /* read length */ 00431 enddata = buf + mylen; 00432 if (enddata - buf < 3) 00433 goto exit; 00434 00435 if (MQTTSNPacket_readChar(&curdata) != MQTTSN_WILLTOPICRESP) 00436 goto exit; 00437 00438 *resp_rc = MQTTSNPacket_readChar(&curdata); 00439 00440 rc = 1; 00441 exit: 00442 FUNC_EXIT_RC(rc); 00443 return rc; 00444 } 00445 00446 00447 /** 00448 * Deserializes the supplied (wire) buffer into willmsgresp data - return code 00449 * @param connack_rc returned integer value of the return code 00450 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00451 * @param len the length in bytes of the data in the supplied buffer 00452 * @return error code. 1 is success, 0 is failure 00453 */ 00454 int MQTTSNDeserialize_willmsgresp(int* resp_rc, unsigned char* buf, int buflen) 00455 { 00456 unsigned char* curdata = buf; 00457 unsigned char* enddata = NULL; 00458 int rc = 0; 00459 int mylen; 00460 00461 FUNC_ENTRY; 00462 curdata += (rc = MQTTSNPacket_decode(curdata, buflen, &mylen)); /* read length */ 00463 enddata = buf + mylen; 00464 if (enddata - buf < 3) 00465 goto exit; 00466 00467 if (MQTTSNPacket_readChar(&curdata) != MQTTSN_WILLMSGRESP) 00468 goto exit; 00469 00470 *resp_rc = MQTTSNPacket_readChar(&curdata); 00471 00472 rc = 1; 00473 exit: 00474 FUNC_EXIT_RC(rc); 00475 return rc; 00476 } 00477 00478 00479
Generated on Tue Jul 12 2022 20:35:37 by 1.7.2