Low level MQTTSN packet library, part of the Eclipse Paho project: http://eclipse.org/paho

Dependents:   MQTTSN sara-n200-hello-mqtt-sn MQTTSN_2

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   * 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