Andrew Reed / Mbed OS CITY1082-i2c_master_wifi_mqtt
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MQTTSNConnectClient.c Source File

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