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 MQTTSNConnectServer.c Source File

MQTTSNConnectServer.c

00001 /*******************************************************************************
00002  * Copyright (c) 2014 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  *******************************************************************************/
00016 
00017 #include "StackTrace.h"
00018 #include "MQTTSNPacket.h"
00019 #include <string.h>
00020 
00021 #define min(a, b) ((a < b) ? 1 : 0)
00022 
00023 
00024 /**
00025   * Deserializes the supplied (wire) buffer into connect data structure
00026   * @param data the connect data structure to be filled out
00027   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00028   * @param len the length in bytes of the data in the supplied buffer
00029   * @return error code.  1 is success, 0 is failure
00030   */
00031 int MQTTSNDeserialize_connect(MQTTSNPacket_connectData* data, unsigned char* buf, int len)
00032 {
00033     MQTTSNFlags flags = {0};
00034     unsigned char* curdata = buf;
00035     unsigned char* enddata = &buf[len];
00036     int rc = 0;
00037     int version = 0;
00038     int mylen = 0;
00039 
00040     FUNC_ENTRY;
00041     curdata += (rc = MQTTSNPacket_decode(curdata, len, &mylen)); /* read length */
00042     enddata = buf + mylen;
00043     if (enddata - curdata < 2)
00044         goto exit;
00045 
00046     if (MQTTSNPacket_readChar(&curdata) != MQTTSN_CONNECT)
00047         goto exit;
00048 
00049     flags.all = MQTTSNPacket_readChar(&curdata);
00050     data->cleansession = flags.bits.cleanSession;
00051     data->willFlag = flags.bits.will;
00052 
00053     if ((version = (int)MQTTSNPacket_readChar(&curdata)) != 1) /* Protocol version */
00054         goto exit;
00055 
00056     data->duration = MQTTSNPacket_readInt(&curdata);
00057 
00058     if (!readMQTTSNString(&data->clientID, &curdata, enddata))
00059         goto exit;
00060 
00061     rc = 1;
00062 exit:
00063     FUNC_EXIT_RC(rc);
00064     return rc;
00065 }
00066 
00067 
00068 /**
00069   * Serializes the connack packet into the supplied buffer.
00070   * @param buf the buffer into which the packet will be serialized
00071   * @param buflen the length in bytes of the supplied buffer
00072   * @param connack_rc the integer connack return code to be used 
00073   * @return serialized length, or error if 0
00074   */
00075 int MQTTSNSerialize_connack(unsigned char* buf, int buflen, int connack_rc)
00076 {
00077     int rc = 0;
00078     unsigned char *ptr = buf;
00079 
00080     FUNC_ENTRY;
00081     if (buflen < 3)
00082     {
00083         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00084         goto exit;
00085     }
00086 
00087     ptr += MQTTSNPacket_encode(ptr, 3); /* write length */
00088     MQTTSNPacket_writeChar(&ptr, MQTTSN_CONNACK);
00089     MQTTSNPacket_writeChar(&ptr, connack_rc);
00090 
00091     rc = ptr - buf;
00092 exit:
00093     FUNC_EXIT_RC(rc);
00094     return rc;
00095 }
00096 
00097 
00098 /**
00099   * Deserializes the supplied (wire) buffer into disconnect data - optional duration
00100   * @param duration returned integer value of the duration field, -1 if no duration was specified
00101   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00102   * @param len the length in bytes of the data in the supplied buffer
00103   * @return error code.  1 is success, 0 is failure
00104   */
00105 int MQTTSNDeserialize_disconnect(int* duration, unsigned char* buf, int buflen)
00106 {
00107     unsigned char* curdata = buf;
00108     unsigned char* enddata = NULL;
00109     int rc = -1;
00110     int mylen;
00111 
00112     FUNC_ENTRY;
00113     curdata += (rc = MQTTSNPacket_decode(curdata, buflen, &mylen)); /* read length */
00114     enddata = buf + mylen;
00115     if (enddata - curdata < 1)
00116         goto exit;
00117 
00118     if (MQTTSNPacket_readChar(&curdata) != MQTTSN_DISCONNECT)
00119         goto exit;
00120 
00121     if (enddata - curdata == 2)
00122         *duration = MQTTSNPacket_readInt(&curdata);
00123     else if (enddata != curdata)
00124         goto exit;
00125 
00126     rc = 1;
00127 exit:
00128     FUNC_EXIT_RC(rc);
00129     return rc;
00130 }
00131 
00132 
00133 /**
00134   * Serializes a willtopicreq packet into the supplied buffer.
00135   * @param buf the buffer into which the packet will be serialized
00136   * @param buflen the length in bytes of the supplied buffer
00137   * @return serialized length, or error if 0
00138   */
00139 int MQTTSNSerialize_willtopicreq(unsigned char* buf, int buflen)
00140 {
00141     int rc = 0;
00142     unsigned char *ptr = buf;
00143 
00144     FUNC_ENTRY;
00145     if (buflen < 2)
00146     {
00147         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00148         goto exit;
00149     }
00150 
00151     ptr += MQTTSNPacket_encode(ptr, 2); /* write length */
00152     MQTTSNPacket_writeChar(&ptr, MQTTSN_WILLTOPICREQ);
00153 
00154     rc = ptr - buf;
00155 exit:
00156     FUNC_EXIT_RC(rc);
00157     return rc;
00158 }
00159 
00160 
00161 /**
00162   * Serializes a willmsgreq packet into the supplied buffer.
00163   * @param buf the buffer into which the packet will be serialized
00164   * @param buflen the length in bytes of the supplied buffer
00165   * @return serialized length, or error if 0
00166   */
00167 int MQTTSNSerialize_willmsgreq(unsigned char* buf, int buflen)
00168 {
00169     int rc = 0;
00170     unsigned char *ptr = buf;
00171 
00172     FUNC_ENTRY;
00173     if (buflen < 2)
00174     {
00175         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00176         goto exit;
00177     }
00178 
00179     ptr += MQTTSNPacket_encode(ptr, 2); /* write length */
00180     MQTTSNPacket_writeChar(&ptr, MQTTSN_WILLMSGREQ);
00181 
00182     rc = ptr - buf;
00183 exit:
00184     FUNC_EXIT_RC(rc);
00185     return rc;
00186 }
00187 
00188 
00189 
00190 /**
00191   * Deserializes the supplied (wire) buffer into pingreq data
00192   * @param clientID the connect data structure to be filled out
00193   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00194   * @param len the length in bytes of the data in the supplied buffer
00195   * @return error code.  1 is success, 0 is failure
00196   */
00197 int MQTTSNDeserialize_pingreq(MQTTSNString* clientID, unsigned char* buf, int len)
00198 {
00199     unsigned char* curdata = buf;
00200     unsigned char* enddata = &buf[len];
00201     int rc = 0;
00202     int mylen = 0;
00203 
00204     FUNC_ENTRY;
00205     curdata += (rc = MQTTSNPacket_decode(curdata, len, &mylen)); /* read length */
00206     enddata = buf + mylen;
00207     if (enddata - curdata < 1)
00208         goto exit;
00209 
00210     if (MQTTSNPacket_readChar(&curdata) != MQTTSN_PINGREQ)
00211         goto exit;
00212 
00213     if (!readMQTTSNString(clientID, &curdata, enddata))
00214         goto exit;
00215 
00216     rc = 1;
00217 exit:
00218     FUNC_EXIT_RC(rc);
00219     return rc;
00220 }
00221 
00222 
00223 /**
00224   * Serializes a pingresp packet into the supplied buffer.
00225   * @param buf the buffer into which the packet will be serialized
00226   * @param buflen the length in bytes of the supplied buffer
00227   * @return serialized length, or error if 0
00228   */
00229 int MQTTSNSerialize_pingresp(unsigned char* buf, int buflen)
00230 {
00231     int rc = 0;
00232     unsigned char *ptr = buf;
00233 
00234     FUNC_ENTRY;
00235     if (buflen < 2)
00236     {
00237         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00238         goto exit;
00239     }
00240 
00241     ptr += MQTTSNPacket_encode(ptr, 2); /* write length */
00242     MQTTSNPacket_writeChar(&ptr, MQTTSN_PINGRESP);
00243 
00244     rc = ptr - buf;
00245 exit:
00246     FUNC_EXIT_RC(rc);
00247     return rc;
00248 }
00249 
00250 
00251 /**
00252   * Deserializes the supplied (wire) buffer into willtopic or willtopicupd data structure
00253   * @param data the connect data structure to be filled out
00254   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00255   * @param len the length in bytes of the data in the supplied buffer
00256   * @return error code.  1 is success, 0 is failure
00257   */
00258 int MQTTSNDeserialize_willtopic1(int *willQoS, unsigned char *willRetain, MQTTSNString* willTopic, unsigned char* buf, int len,
00259         enum MQTTSN_msgTypes packet_type)
00260 {
00261     MQTTSNFlags flags = {0};
00262     unsigned char* curdata = buf;
00263     unsigned char* enddata = &buf[len];
00264     int rc = 0;
00265     int mylen = 0;
00266 
00267     FUNC_ENTRY;
00268     curdata += (rc = MQTTSNPacket_decode(curdata, len, &mylen)); /* read length */
00269     enddata = buf + mylen;
00270     if (enddata > buf + len)
00271         goto exit;
00272 
00273     if (MQTTSNPacket_readChar(&curdata) != packet_type)
00274         goto exit;
00275 
00276     flags.all = MQTTSNPacket_readChar(&curdata);
00277     *willQoS = flags.bits.QoS;
00278     *willRetain = flags.bits.retain;
00279 
00280     if (!readMQTTSNString(willTopic, &curdata, enddata))
00281         goto exit;
00282 
00283     rc = 1;
00284 exit:
00285     FUNC_EXIT_RC(rc);
00286     return rc;
00287 }
00288 
00289 
00290 /**
00291   * Deserializes the supplied (wire) buffer into willtopic data structure
00292   * @param data the connect data structure to be filled out
00293   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00294   * @param len the length in bytes of the data in the supplied buffer
00295   * @return error code.  1 is success, 0 is failure
00296   */
00297 int MQTTSNDeserialize_willtopic(int *willQoS, unsigned char *willRetain, MQTTSNString* willTopic, unsigned char* buf, int len)
00298 {
00299     return MQTTSNDeserialize_willtopic1(willQoS, willRetain, willTopic, buf, len, MQTTSN_WILLTOPIC);
00300 }
00301 
00302 /**
00303   * Deserializes the supplied (wire) buffer into willtopic data structure
00304   * @param data the connect data structure to be filled out
00305   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00306   * @param len the length in bytes of the data in the supplied buffer
00307   * @return error code.  1 is success, 0 is failure
00308   */
00309 int MQTTSNDeserialize_willtopicupd(int *willQoS, unsigned char *willRetain, MQTTSNString* willTopic, unsigned char* buf, int len)
00310 {
00311     return MQTTSNDeserialize_willtopic1(willQoS, willRetain, willTopic, buf, len, MQTTSN_WILLTOPICUPD);
00312 }
00313 
00314 
00315 /**
00316   * Deserializes the supplied (wire) buffer into willmsg or willmsgupd data
00317   * @param willMsg the will message to be retrieved
00318   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00319   * @param len the length in bytes of the data in the supplied buffer
00320   * @return error code.  1 is success, 0 is failure
00321   */
00322 int MQTTSNDeserialize_willmsg1(MQTTSNString* willMsg, unsigned char* buf, int len, enum MQTTSN_msgTypes packet_type)
00323 {
00324     unsigned char* curdata = buf;
00325     unsigned char* enddata = &buf[len];
00326     int rc = 0;
00327     int mylen = 0;
00328 
00329     FUNC_ENTRY;
00330     curdata += (rc = MQTTSNPacket_decode(curdata, len, &mylen)); /* read length */
00331     enddata = buf + mylen;
00332     if (enddata > buf + len)
00333         goto exit;
00334 
00335     if (MQTTSNPacket_readChar(&curdata) != packet_type)
00336         goto exit;
00337 
00338     if (!readMQTTSNString(willMsg, &curdata, enddata))
00339         goto exit;
00340 
00341     rc = 1;
00342 exit:
00343     FUNC_EXIT_RC(rc);
00344     return rc;
00345 }
00346 
00347 
00348 /**
00349   * Deserializes the supplied (wire) buffer into willmsg data
00350   * @param willMsg the will message to be retrieved
00351   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00352   * @param len the length in bytes of the data in the supplied buffer
00353   * @return error code.  1 is success, 0 is failure
00354   */
00355 int MQTTSNDeserialize_willmsg(MQTTSNString* willMsg, unsigned char* buf, int len)
00356 {
00357     return MQTTSNDeserialize_willmsg1(willMsg, buf, len, MQTTSN_WILLMSG);
00358 }
00359 
00360 /**
00361   * Deserializes the supplied (wire) buffer into willmsgupd data
00362   * @param willMsg the will message to be retrieved
00363   * @param buf the raw buffer data, of the correct length determined by the remaining length field
00364   * @param len the length in bytes of the data in the supplied buffer
00365   * @return error code.  1 is success, 0 is failure
00366   */
00367 int MQTTSNDeserialize_willmsgupd(MQTTSNString* willMsg, unsigned char* buf, int len)
00368 {
00369     return MQTTSNDeserialize_willmsg1(willMsg, buf, len, MQTTSN_WILLMSGUPD);
00370 }
00371 
00372 
00373 /**
00374   * Serializes the willtopicresp packet into the supplied buffer.
00375   * @param buf the buffer into which the packet will be serialized
00376   * @param buflen the length in bytes of the supplied buffer
00377   * @param rc the integer return code to be used
00378   * @return serialized length, or error if 0
00379   */
00380 int MQTTSNSerialize_willtopicresp(unsigned char* buf, int buflen, int resp_rc)
00381 {
00382     int rc = 0;
00383     unsigned char *ptr = buf;
00384 
00385     FUNC_ENTRY;
00386     if (buflen < 3)
00387     {
00388         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00389         goto exit;
00390     }
00391 
00392     ptr += MQTTSNPacket_encode(ptr, 3); /* write length */
00393     MQTTSNPacket_writeChar(&ptr, MQTTSN_WILLTOPICRESP);
00394     MQTTSNPacket_writeChar(&ptr, resp_rc);
00395 
00396     rc = ptr - buf;
00397 exit:
00398     FUNC_EXIT_RC(rc);
00399     return rc;
00400 }
00401 
00402 
00403 /**
00404   * Serializes the willmsgresp packet into the supplied buffer.
00405   * @param buf the buffer into which the packet will be serialized
00406   * @param buflen the length in bytes of the supplied buffer
00407   * @param rc the integer return code to be used
00408   * @return serialized length, or error if 0
00409   */
00410 int MQTTSNSerialize_willmsgresp(unsigned char* buf, int buflen, int resp_rc)
00411 {
00412     int rc = 0;
00413     unsigned char *ptr = buf;
00414 
00415     FUNC_ENTRY;
00416     if (buflen < 3)
00417     {
00418         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00419         goto exit;
00420     }
00421 
00422     ptr += MQTTSNPacket_encode(ptr, 3); /* write length */
00423     MQTTSNPacket_writeChar(&ptr, MQTTSN_WILLMSGRESP);
00424     MQTTSNPacket_writeChar(&ptr, resp_rc);
00425 
00426     rc = ptr - buf;
00427 exit:
00428     FUNC_EXIT_RC(rc);
00429     return rc;
00430 }
00431