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

« Back to documentation index

Show/hide line numbers MQTTSNSerializePublish.c Source File

MQTTSNSerializePublish.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 "MQTTSNPacket.h"
00018 #include "StackTrace.h"
00019 
00020 #include <string.h>
00021 
00022 
00023 /**
00024   * Determines the length of the MQTT publish packet that would be produced using the supplied parameters
00025   * @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)
00026   * @param topicName the topic name to be used in the publish  
00027   * @param payloadlen the length of the payload to be sent
00028   * @return the length of buffer needed to contain the serialized version of the packet
00029   */
00030 int MQTTSNSerialize_publishLength(int payloadlen, MQTTSN_topicid topic, int qos)
00031 {
00032     int len = 6;
00033 
00034     if (topic.type == MQTTSN_TOPIC_TYPE_NORMAL && qos == 3)
00035         len += topic.data.long_.len;
00036 
00037     return payloadlen + len;
00038 }
00039 
00040 
00041 /**
00042   * Serializes the supplied publish data into the supplied buffer, ready for sending
00043   * @param buf the buffer into which the packet will be serialized
00044   * @param buflen the length in bytes of the supplied buffer
00045   * @param dup integer - the MQTT dup flag
00046   * @param qos integer - the MQTT QoS value
00047   * @param retained integer - the MQTT retained flag
00048   * @param packetid integer - the MQTT packet identifier
00049   * @param topic MQTTSN_topicid - the MQTT topic in the publish
00050   * @param payload byte buffer - the MQTT publish payload
00051   * @param payloadlen integer - the length of the MQTT payload
00052   * @return the length of the serialized data.  <= 0 indicates error
00053   */
00054 int MQTTSNSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
00055         MQTTSN_topicid topic, unsigned char* payload, int payloadlen)
00056 {
00057     unsigned char *ptr = buf;
00058     MQTTSNFlags flags;
00059     int len = 0;
00060     int rc = 0;
00061 
00062     FUNC_ENTRY;
00063     if ((len = MQTTSNPacket_len(MQTTSNSerialize_publishLength(payloadlen, topic, qos))) > buflen)
00064     {
00065         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00066         goto exit;
00067     }
00068     ptr += MQTTSNPacket_encode(ptr, len); /* write length */
00069     writeChar(&ptr, MQTTSN_PUBLISH);      /* write message type */
00070 
00071     flags.all = 0;
00072     flags.bits.dup = dup;
00073     flags.bits.QoS = qos;
00074     flags.bits.retain = retained;
00075     flags.bits.topicIdType = topic.type;
00076     writeChar(&ptr, flags.all);
00077 
00078     if (topic.type == MQTTSN_TOPIC_TYPE_NORMAL && qos == 3)
00079     {
00080         /* special arrangement for long topic names in QoS -1 publishes.  The length of the topic is in the topicid field */
00081         writeInt(&ptr, topic.data.long_.len); /* topic length */
00082     }
00083     else if (topic.type == MQTTSN_TOPIC_TYPE_NORMAL || topic.type == MQTTSN_TOPIC_TYPE_PREDEFINED)
00084         writeInt(&ptr, topic.data.id);
00085     else
00086     {
00087         writeChar(&ptr, topic.data.short_name[0]);
00088         writeChar(&ptr, topic.data.short_name[1]);
00089     }
00090     writeInt(&ptr, packetid);
00091     if (topic.type == MQTTSN_TOPIC_TYPE_NORMAL && qos == 3)
00092     {
00093         memcpy(ptr, topic.data.long_.name, topic.data.long_.len);
00094         ptr += topic.data.long_.len;
00095     }
00096     memcpy(ptr, payload, payloadlen);
00097     ptr += payloadlen;
00098 
00099     rc = ptr - buf;
00100 exit:
00101     FUNC_EXIT_RC(rc);
00102     return rc;
00103 }
00104 
00105 
00106 int MQTTSNSerialize_puback(unsigned char* buf, int buflen, unsigned short topicid, unsigned short packetid,
00107         unsigned char returncode)
00108 {
00109     unsigned char *ptr = buf;
00110     int len = 0;
00111     int rc = 0;
00112 
00113     FUNC_ENTRY;
00114     if ((len = MQTTSNPacket_len(6)) > buflen)
00115     {
00116         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00117         goto exit;
00118     }
00119     ptr += MQTTSNPacket_encode(ptr, len); /* write length */
00120     writeChar(&ptr, MQTTSN_PUBACK);      /* write message type */
00121 
00122     writeInt(&ptr, topicid);
00123     writeInt(&ptr, packetid);
00124     writeChar(&ptr, returncode);
00125 
00126     rc = ptr - buf;
00127 exit:
00128     FUNC_EXIT_RC(rc);
00129     return rc;
00130 
00131 }
00132 
00133 
00134 
00135 /**
00136   * Serializes the ack packet into the supplied buffer.
00137   * @param buf the buffer into which the packet will be serialized
00138   * @param buflen the length in bytes of the supplied buffer
00139   * @param type the MQTT-SN packet type
00140   * @param packetid the MQTT-SN packet identifier
00141   * @return serialized length, or error if 0
00142   */
00143 int MQTTSNSerialize_ack(unsigned char* buf, int buflen, unsigned short packet_type, unsigned short packetid)
00144 {
00145     int rc = 0;
00146     unsigned char *ptr = buf;
00147     int len = 4; /* ack packet length */
00148 
00149     FUNC_ENTRY;
00150     if (len > buflen)
00151     {
00152         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00153         goto exit;
00154     }
00155     ptr += MQTTSNPacket_encode(ptr, len); /* write length */
00156     writeChar(&ptr, packet_type);      /* write packet type */
00157 
00158     writeInt(&ptr, packetid);
00159 
00160     rc = ptr - buf;
00161 exit:
00162     FUNC_EXIT_RC(rc);
00163     return rc;
00164 }
00165 
00166 
00167 /**
00168   * Serializes a puback packet into the supplied buffer.
00169   * @param buf the buffer into which the packet will be serialized
00170   * @param buflen the length in bytes of the supplied buffer
00171   * @param packetid integer - the MQTT packet identifier
00172   * @return serialized length, or error if 0
00173   */
00174 int MQTTSNSerialize_pubrec(unsigned char* buf, int buflen, unsigned short packetid)
00175 {
00176     return MQTTSNSerialize_ack(buf, buflen, MQTTSN_PUBREC, packetid);
00177 }
00178 
00179 
00180 /**
00181   * Serializes a pubrel packet into the supplied buffer.
00182   * @param buf the buffer into which the packet will be serialized
00183   * @param buflen the length in bytes of the supplied buffer
00184   * @param dup integer - the MQTT dup flag
00185   * @param packetid integer - the MQTT packet identifier
00186   * @return serialized length, or error if 0
00187   */
00188 int MQTTSNSerialize_pubrel(unsigned char* buf, int buflen, unsigned short packetid)
00189 {
00190     return MQTTSNSerialize_ack(buf, buflen, MQTTSN_PUBREL, packetid);
00191 }
00192 
00193 
00194 /**
00195   * Serializes a pubrel packet into the supplied buffer.
00196   * @param buf the buffer into which the packet will be serialized
00197   * @param buflen the length in bytes of the supplied buffer
00198   * @param packetid integer - the MQTT packet identifier
00199   * @return serialized length, or error if 0
00200   */
00201 int MQTTSNSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid)
00202 {
00203     return MQTTSNSerialize_ack(buf, buflen, MQTTSN_PUBCOMP, packetid);
00204 }
00205 
00206 
00207 /**
00208   * Determines the length of the MQTT register packet that would be produced using the supplied parameters
00209   * @param topicnamelen the length of the topic name to be used in the register
00210   * @return the length of buffer needed to contain the serialized version of the packet
00211   */
00212 int MQTTSNSerialize_registerLength(int topicnamelen)
00213 {
00214     return topicnamelen + 5;
00215 }
00216 
00217 /**
00218   * Serializes the supplied register data into the supplied buffer, ready for sending
00219   * @param buf the buffer into which the packet will be serialized
00220   * @param buflen the length in bytes of the supplied buffer
00221   * @param topicid if sent by a gateway, contains the id for the topicname, otherwise 0
00222   * @param packetid integer - the MQTT packet identifier
00223   * @param topicname null-terminated topic name string
00224   * @return the length of the serialized data.  <= 0 indicates error
00225   */
00226 int MQTTSNSerialize_register(unsigned char* buf, int buflen, unsigned short topicid, unsigned short packetid,
00227         MQTTSNString* topicname)
00228 {
00229     unsigned char *ptr = buf;
00230     int len = 0;
00231     int rc = 0;
00232     int topicnamelen = 0;
00233 
00234     FUNC_ENTRY;
00235     topicnamelen = (topicname->cstring) ? strlen(topicname->cstring) : topicname->lenstring.len;
00236     if ((len = MQTTSNPacket_len(MQTTSNSerialize_registerLength(topicnamelen))) > buflen)
00237     {
00238         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00239         goto exit;
00240     }
00241     ptr += MQTTSNPacket_encode(ptr, len);  /* write length */
00242     writeChar(&ptr, MQTTSN_REGISTER);      /* write message type */
00243 
00244     writeInt(&ptr, topicid);
00245     writeInt(&ptr, packetid);
00246 
00247     memcpy(ptr, (topicname->cstring) ? topicname->cstring : topicname->lenstring.data, topicnamelen);
00248     ptr += topicnamelen;
00249 
00250     rc = ptr - buf;
00251 exit:
00252     FUNC_EXIT_RC(rc);
00253     return rc;
00254 }
00255 
00256 
00257 /**
00258   * Serializes the supplied register data into the supplied buffer, ready for sending
00259   * @param buf the buffer into which the packet will be serialized
00260   * @param buflen the length in bytes of the supplied buffer
00261   * @param topicid if sent by a gateway, contains the id for the topicname, otherwise 0
00262   * @param packetid integer - the MQTT packet identifier
00263   * @param return_code integer return code
00264   * @return the length of the serialized data.  <= 0 indicates error
00265   */
00266 int MQTTSNSerialize_regack(unsigned char* buf, int buflen, unsigned short topicid, unsigned short packetid,
00267         unsigned char return_code)
00268 {
00269     unsigned char *ptr = buf;
00270     int len = 0;
00271     int rc = 0;
00272 
00273     FUNC_ENTRY;
00274     if ((len = MQTTSNPacket_len(6)) > buflen)
00275     {
00276         rc = MQTTSNPACKET_BUFFER_TOO_SHORT;
00277         goto exit;
00278     }
00279     ptr += MQTTSNPacket_encode(ptr, len);  /* write length */
00280     writeChar(&ptr, MQTTSN_REGACK);      /* write message type */
00281 
00282     writeInt(&ptr, topicid);
00283     writeInt(&ptr, packetid);
00284     writeChar(&ptr, return_code);
00285 
00286     rc = ptr - buf;
00287 exit:
00288     FUNC_EXIT_RC(rc);
00289     return rc;
00290 }